Compare commits
412 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b446f2630e | |||
| 224567f980 | |||
| 2b31792f06 | |||
| 613f0e9795 | |||
| f1162ed4a4 | |||
| 8039ada222 | |||
| df36ce68df | |||
| f24251118e | |||
| d2e926fbf7 | |||
| 854bf922a4 | |||
| e975555896 | |||
| 8d6581ea13 | |||
| 59169a221d | |||
| b1498c321b | |||
| 62b1618fbd | |||
| ab2dbb7dc7 | |||
| be474ea595 | |||
| cd31eaf572 | |||
| 51719d23a4 | |||
| 81013e1310 | |||
| 6d1f17adee | |||
| ddc25372c1 | |||
| 28f35f3ec7 | |||
| 0a40c4c596 | |||
| cef15011c2 | |||
| 7bf792b467 | |||
| 55e0e323b9 | |||
| 02f7c3c9d0 | |||
| 209db9f11a | |||
| be6437c46f | |||
| a94ddc504f | |||
| 12a3330b78 | |||
| dbad24b81b | |||
| a2046f018e | |||
| 454e9c5870 | |||
| 2f337dab13 | |||
| 42adfe29c8 | |||
| 8287ad960a | |||
| aa6090c04b | |||
| 327dd44992 | |||
| 0e11d4812a | |||
| 676a3d175e | |||
| 34358ab33d | |||
| 5ccaf40ad0 | |||
| 51abe5d1ff | |||
| 2dea824cc0 | |||
| 055888e181 | |||
| 67ba17cc8a | |||
| e1ef14dbcc | |||
| 685d54f2cb | |||
| 490f36099f | |||
| f9ff2b22f2 | |||
| 0ac4c7b8a9 | |||
| 47f6f0f239 | |||
| c27314f896 | |||
| 1b68c55763 | |||
| ed313db742 | |||
| f435ae32ce | |||
| 548d3677f0 | |||
| b0e0bd23c9 | |||
| 2bd5e981bc | |||
| 5de728612e | |||
| 64019ee28d | |||
| 6cad77328b | |||
| 26ac35ad40 | |||
| 31514d1943 | |||
| 52ea452010 | |||
| c469e0acc3 | |||
| f05f9ca735 | |||
| 1d76f93304 | |||
| 05e904e613 | |||
| 095f6fde47 | |||
| 1130bbc090 | |||
| 76f984ce7c | |||
| 6535ad597f | |||
| 40f81b4d2b | |||
| 54ca601e8f | |||
| de549cac05 | |||
| 83d474b13d | |||
| 9480ef06ab | |||
| c099e8eb27 | |||
| 1325f05432 | |||
| cfd19ae232 | |||
| cb6ff8738b | |||
| 81ebb8b6c0 | |||
| 9bdd00ea5a | |||
| 6f35e543ca | |||
| ee61270e1b | |||
| e902b74267 | |||
| 3eb6d9ea8e | |||
| 98d87d7573 | |||
| f7fea1f779 | |||
| 1f834863a7 | |||
| e4846a2046 | |||
| 0dda593c45 | |||
| 1bfb473c19 | |||
| 3f01baebfe | |||
| 46b61857ab | |||
| 0b214a59a1 | |||
| 77579669f2 | |||
| 2c5c99c0c7 | |||
| a3f9e7f638 | |||
| 4e67393d27 | |||
| cb0933a908 | |||
| af95461a70 | |||
| 79b3a61ac8 | |||
| a9e3b659d3 | |||
| af9584a174 | |||
| 63827c9dcb | |||
| 809175612c | |||
| 06d9ef24f1 | |||
| f37a1fd6dc | |||
| badcd0e0be | |||
| 22683f6910 | |||
| 7ffa1b06ee | |||
| 418e38ee46 | |||
| 6ac5507e4e | |||
| 9bcef1774d | |||
| edecfdb5bc | |||
| 74670c00a6 | |||
| bd9b02f364 | |||
| 05b615c858 | |||
| e13562e4cb | |||
| c7f7f87321 | |||
| 11532a36fb | |||
| 121f673328 | |||
| f5b69df11a | |||
| 7cc27d45a4 | |||
| 9c20f4142c | |||
| 7b7a92e35a | |||
| 33ab7ba747 | |||
| 1b9f601c41 | |||
| b2ddf59db4 | |||
| a0d737ba51 | |||
| db207807cb | |||
| 1d090b33f5 | |||
| 700aae8a31 | |||
| fbdff0b178 | |||
| 018549c3c7 | |||
| 63e8755be5 | |||
| c8aaa79ab6 | |||
| 194e44f52a | |||
| efd47a9586 | |||
| f1ecf5bc68 | |||
| 719079581a | |||
| f8d8de53e8 | |||
| baa37eba07 | |||
| 8933343433 | |||
| e4e1d3fb92 | |||
| dac989c697 | |||
| 5969d670d0 | |||
| 39990f2818 | |||
| 8dfcb5e612 | |||
| 4d91053f8c | |||
| ff503d08a7 | |||
| 0ee8c00c5f | |||
| d4e122a1f8 | |||
| 5508194189 | |||
| ded11645e3 | |||
| 7afbba4c3f | |||
| bf439043cf | |||
| 24ce746b91 | |||
| 98920bd860 | |||
| fbcbdfca62 | |||
| 6ae8890092 | |||
| c113e23001 | |||
| b58a61c0b3 | |||
| 936080d710 | |||
| 10675f7125 | |||
| 39e4aa1976 | |||
| 5dffb1ebb0 | |||
| 56df2c45e5 | |||
| 4c719d776a | |||
| da1d2cd36a | |||
| 7ed1e576b2 | |||
| 8030c44af4 | |||
| 2f935a56b9 | |||
| 830d7a2b23 | |||
| 5cbe0a38ca | |||
| c477ded1b5 | |||
| 3040ea8a97 | |||
| 9ad640a5c4 | |||
| 109fb1b506 | |||
| 55e13047e4 | |||
| 75a0f2e981 | |||
| d935229711 | |||
| 91e1d5baad | |||
| 8de8afbab8 | |||
| 75df2e52c1 | |||
| 40e699209f | |||
| 256ebcead0 | |||
| 44bfb74932 | |||
| 97c84a3963 | |||
| b493c2d6b0 | |||
| 4ea03b0597 | |||
| 7b08c94bdb | |||
| 92f7c7dfd9 | |||
| 358215a92f | |||
| 867513dc79 | |||
| 583a76b150 | |||
| 2a62a94b09 | |||
| 05d65ed797 | |||
| 1e04f82fe2 | |||
| 596f0ad16c | |||
| 296bf195ce | |||
| ba0793127c | |||
| 06711cfb20 | |||
| 8628e4024d | |||
| 1b912020ea | |||
| 3093f80196 | |||
| 6b67b3df63 | |||
| e9fee163a9 | |||
| e24ad77ab5 | |||
| c56e0ae7f8 | |||
| ed9ffe76a7 | |||
| 0622ebf534 | |||
| 63b0105d05 | |||
| 3ad53733e8 | |||
| 403913a0fc | |||
| 9f2a237aaf | |||
| b967772897 | |||
| e19617a065 | |||
| 9bd56c993c | |||
| f62b5d248c | |||
| 711f5455df | |||
| e36efff00d | |||
| 486bae633b | |||
| 228a006953 | |||
| 2d40afe7ef | |||
| ff55b6e4e0 | |||
| e2de295c41 | |||
| ea38601564 | |||
| 9fd32ad44b | |||
| dd753184db | |||
| e8097caed7 | |||
| eb7e37dcf1 | |||
| f24bba21e9 | |||
| 1a1297c12a | |||
| af308ea5c8 | |||
| 6382d6f9c7 | |||
| 1ae6c5708c | |||
| 93bad99d79 | |||
| 9c68a3ba3d | |||
| 117710d449 | |||
| b07130acc6 | |||
| bb96092d74 | |||
| 9907df1db8 | |||
| ab3d4ca865 | |||
| e424d85a93 | |||
| e5a133b3da | |||
| 15e9473533 | |||
| 20333e6214 | |||
| 5d1ee20076 | |||
| 576d407c00 | |||
| 3eb0154d58 | |||
| 80663fff97 | |||
| 27aa98c269 | |||
| 9789a1969c | |||
| d333c7dc08 | |||
| edfc1a403f | |||
| ad37629f0a | |||
| 7be19b20cd | |||
| 5b2eb9f599 | |||
| ede75b1c5b | |||
| cdb0e823aa | |||
| a35190b7bf | |||
| 4b180d8d66 | |||
| 61615ddc0f | |||
| 0ecb387f58 | |||
| 3840a1734d | |||
| ca990e8d53 | |||
| c9010c5c58 | |||
| 2ea716a017 | |||
| 4e4ad32f97 | |||
| faa1360f33 | |||
| 64dc50f3fb | |||
| 1ac35b5d56 | |||
| 1dd456a6ca | |||
| be01694383 | |||
| b8b88d998c | |||
| bf4d9421e0 | |||
| 67f9d631bd | |||
| 311d62cc02 | |||
| 46a75c4d98 | |||
| fececc4e51 | |||
| d0b4c7ee59 | |||
| e6af8d207a | |||
| 75b9930ee4 | |||
| 86b1d7fad9 | |||
| 2aab998b62 | |||
| 6b22017721 | |||
| 34aef1aa18 | |||
| d00762d1f7 | |||
| 400f08c20d | |||
| 18c7f1cd76 | |||
| 74506dd4e6 | |||
| 0f72356cb1 | |||
| 121fb24705 | |||
| 867c658f4f | |||
| 0704355a7f | |||
| 6930a38997 | |||
| e218dc5947 | |||
| 7e1c13c6c2 | |||
| e87701228d | |||
| d6751e0f07 | |||
| b04a041c2d | |||
| 8218fcb17b | |||
| 86bdb036bd | |||
| eefc2eaf0f | |||
| ebed56674e | |||
| ce4cab0a23 | |||
| 9913820366 | |||
| 640053d727 | |||
| aaf00829d3 | |||
| 094f5ab1b4 | |||
| a0380fe1f7 | |||
| 9864410eb8 | |||
| 450b2135b6 | |||
| a58a22cc6a | |||
| 0c9b8826c9 | |||
| 74f6b75db2 | |||
| b8821f5ea3 | |||
| 8f1a260d96 | |||
| a69613b4e0 | |||
| e7cae825bd | |||
| 486570d2b8 | |||
| ce576db0dc | |||
| 53f6f57420 | |||
| 814d2f6c03 | |||
| 006ff40175 | |||
| aedee33ca9 | |||
| 6ee6e21eb5 | |||
| add5d62cec | |||
| fa604849fe | |||
| 34004904e7 | |||
| 4df9f61347 | |||
| 14ca7cf7d6 | |||
| 57a60c1309 | |||
| bef825c0d8 | |||
| 93354e7a3e | |||
| f173a32fa3 | |||
| 7566b8c650 | |||
| 2eaef1f586 | |||
| 1341e93fca | |||
| 06864b0199 | |||
| a16b25275e | |||
| abffce6424 | |||
| c948a7778b | |||
| bd1fe5995f | |||
| 6791069bca | |||
| 3e6add90de | |||
| 8dd4d15b1f | |||
| 2a83e530e9 | |||
| e5d763860c | |||
| 9e4b401f9b | |||
| 2c304eafad | |||
| 70d6ac9daf | |||
| 5b3804ac08 | |||
| d3331d1e22 | |||
| bd619229b2 | |||
| 182097ef1c | |||
| 0b7ecedcd7 | |||
| da01e4bba0 | |||
| 7c3bfadd5e | |||
| a8bb625513 | |||
| bab8f554bd | |||
| c1b5b2a783 | |||
| 67651669a1 | |||
| ae454cfc01 | |||
| fa218b0d71 | |||
| c29d91a9c4 | |||
| e6ae017609 | |||
| 901cff909e | |||
| 5c8e2dcfcc | |||
| 47dec9cf4d | |||
| 3d40b45fd1 | |||
| 05323c9db5 | |||
| c314946204 | |||
| 7eb9f4051c | |||
| 550183bab2 | |||
| 92c4d245c4 | |||
| a2ab45a461 | |||
| 1d68e299dc | |||
| b987789754 | |||
| e91868a7f6 | |||
| 644cccd3e1 | |||
| e6df88bf42 | |||
| ef823a89c1 | |||
| b169e18de0 | |||
| e822d34342 | |||
| 5590a02dc5 | |||
| 601596f5cb | |||
| 817c4348b1 | |||
| 5963850775 | |||
| 4afef21ca1 | |||
| 2659ec3231 | |||
| 687146ce53 | |||
| a3d6bfc7dd | |||
| e22e2bfc24 | |||
| 0da504735b | |||
| 07f84ac408 | |||
| cd1b2cd7fe | |||
| e1ab73decc | |||
| 21a1e272d9 | |||
| fa21ec5cb6 | |||
| 054c195d56 | |||
| f38b5b85bc | |||
| f1ccc22593 | |||
| a90d197111 | |||
| 9e16988151 | |||
| 91446c69e5 | |||
| 9399374560 |
@@ -0,0 +1,136 @@
|
||||
<claude-mem-context>
|
||||
# Recent Activity
|
||||
|
||||
### Oct 25, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #2374 | 2:55 PM | ✅ | Marketplace metadata version synchronized to 4.2.11 | ~157 |
|
||||
|
||||
### Oct 27, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #2757 | 1:23 AM | 🟣 | Released v4.3.3 with Configurable Session Display and First-Time Setup UX | ~391 |
|
||||
|
||||
### Nov 4, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #3706 | 9:47 PM | ✅ | Marketplace Plugin Version Synchronized to 5.0.2 | ~162 |
|
||||
| #3655 | 3:43 PM | ✅ | Version bumped to 5.0.1 across project | ~354 |
|
||||
|
||||
### Nov 5, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #4068 | 10:58 PM | ✅ | Committed v5.1.0 release with comprehensive release notes | ~486 |
|
||||
| #4066 | 10:57 PM | ✅ | Updated marketplace.json version to 5.1.0 | ~192 |
|
||||
| #3739 | 2:24 PM | ✅ | Updated version to 5.0.3 across project manifests | ~322 |
|
||||
|
||||
### Nov 6, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #4099 | 1:13 PM | 🟣 | Theme Toggle for Light/Dark Mode | ~253 |
|
||||
| #4096 | " | ✅ | Marketplace Metadata Version Sync | ~179 |
|
||||
| #4092 | 1:12 PM | 🔵 | Marketplace Configuration for Claude-Mem Plugin | ~194 |
|
||||
| #4078 | 12:50 PM | 🔴 | Fixed PM2 ENOENT error on Windows systems | ~286 |
|
||||
| #4075 | 12:49 PM | ✅ | Marketplace plugin version synchronized to 5.1.1 | ~189 |
|
||||
|
||||
### Nov 7, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #4612 | 6:33 PM | ✅ | Version Bumped to 5.2.0 Across All Package Metadata | ~359 |
|
||||
| #4598 | 6:31 PM | ✅ | PR #69 Merged: cleanup/worker Branch Integration | ~469 |
|
||||
| #4298 | 11:54 AM | 🔴 | Fixed PostToolUse Hook Schema Compliance | ~310 |
|
||||
| #4295 | 11:53 AM | ✅ | Synchronized Plugin Marketplace Version to 5.1.4 | ~188 |
|
||||
|
||||
### Nov 8, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #5150 | 7:37 PM | 🟣 | Troubleshooting Skill Added to Claude-Mem Plugin | ~427 |
|
||||
| #5133 | 7:29 PM | ✅ | Version 5.2.3 Released with Build Process | ~487 |
|
||||
|
||||
### Nov 9, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #5941 | 7:14 PM | ✅ | Marketplace Version Updated to 5.4.0 | ~157 |
|
||||
|
||||
### Nov 10, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #6341 | 1:49 PM | ✅ | Version Bumped to 5.4.1 | ~239 |
|
||||
|
||||
### Nov 11, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #6602 | 1:51 PM | ✅ | Version 5.4.5 Released to GitHub | ~279 |
|
||||
| #6601 | " | ✅ | Version Patch Bump 5.4.4 to 5.4.5 | ~233 |
|
||||
|
||||
### Nov 14, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #8212 | 3:06 PM | 🔵 | Version Consistency Verification Across Multiple Configuration Files | ~238 |
|
||||
|
||||
### Nov 25, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #14882 | 1:32 PM | 🔵 | Marketplace Configuration Defines Plugin Version and Source Directory | ~366 |
|
||||
|
||||
### Nov 30, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #18064 | 10:52 PM | ✅ | Bumped version to 6.3.7 in marketplace.json | ~179 |
|
||||
| #18060 | 10:51 PM | 🔵 | Read marketplace.json plugin manifest | ~190 |
|
||||
|
||||
### Dec 1, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #18428 | 3:33 PM | 🔵 | Version Conflict in Marketplace Configuration | ~191 |
|
||||
|
||||
### Dec 4, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #20049 | 3:23 PM | ✅ | Updated marketplace.json version to 6.5.2 | ~203 |
|
||||
|
||||
### Dec 9, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #22559 | 1:08 AM | ✅ | Version 7.0.3 committed to repository | ~261 |
|
||||
| #22551 | 1:07 AM | ✅ | Marketplace metadata updated to version 7.0.3 | ~179 |
|
||||
|
||||
### Dec 10, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #23440 | 2:25 PM | ✅ | Marketplace Configuration Updated to 7.0.8 | ~188 |
|
||||
|
||||
### Dec 14, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #26799 | 11:39 PM | ✅ | Marketplace Manifest Version Updated to 7.2.3 | ~248 |
|
||||
| #26796 | " | ✅ | Version Bumped to 7.2.3 in marketplace.json | ~259 |
|
||||
| #26792 | 11:38 PM | 🔵 | Current Version Confirmed as 7.2.2 Across All Configuration Files | ~291 |
|
||||
|
||||
### Dec 16, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #28306 | 10:08 PM | 🔵 | Marketplace Configuration Also Shows Version 7.3.3 | ~220 |
|
||||
| #27555 | 4:48 PM | ✅ | Version bump committed to main branch | ~242 |
|
||||
| #27553 | " | ✅ | Version consistency verified across all configuration files | ~195 |
|
||||
| #27551 | 4:47 PM | ✅ | Marketplace.json version updated to 7.3.1 | ~207 |
|
||||
</claude-mem-context>
|
||||
@@ -10,7 +10,7 @@
|
||||
"plugins": [
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "8.5.8",
|
||||
"version": "10.2.3",
|
||||
"source": "./plugin",
|
||||
"description": "Persistent memory system for Claude Code - context compression across sessions"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"version": "9.0.6",
|
||||
"description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
|
||||
"author": {
|
||||
"name": "Alex Newman"
|
||||
},
|
||||
"repository": "https://github.com/thedotmack/claude-mem",
|
||||
"license": "AGPL-3.0",
|
||||
"keywords": [
|
||||
"memory",
|
||||
"context",
|
||||
"persistence",
|
||||
"hooks",
|
||||
"mcp"
|
||||
]
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
---
|
||||
name: github-morning-reporter
|
||||
description: Use this agent when the user requests a morning report, daily summary, or overview of their GitHub activity. Trigger phrases include 'morning report', 'github report', 'daily github summary', 'what's happening on github', or 'check my github status'. This agent should be used proactively when the user starts their day or explicitly asks for repository updates.\n\nExamples:\n- User: "get me my morning github report"\n Assistant: "I'll use the github-morning-reporter agent to generate your comprehensive GitHub status report."\n <uses Agent tool to invoke github-morning-reporter>\n\n- User: "what's new on my repos today?"\n Assistant: "Let me pull together your GitHub morning report using the github-morning-reporter agent."\n <uses Agent tool to invoke github-morning-reporter>\n\n- User: "show me my daily github summary"\n Assistant: "I'll generate your daily GitHub summary using the github-morning-reporter agent."\n <uses Agent tool to invoke github-morning-reporter>
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
You are an elite GitHub project analyst specializing in delivering actionable morning reports for software development teams. Your expertise lies in synthesizing complex repository activity into clear, prioritized insights that help developers start their day with complete situational awareness.
|
||||
|
||||
## Your Responsibilities
|
||||
|
||||
1. **Fetch Comprehensive GitHub Data**: Use available tools to retrieve:
|
||||
- Open issues across all relevant repositories
|
||||
- Open pull requests with review status
|
||||
- Recent comments, mentions, and @-references
|
||||
- CI/CD status for active PRs
|
||||
- Stale issues/PRs (no activity in 7+ days)
|
||||
|
||||
2. **Intelligent Grouping and Deduplication**:
|
||||
- Identify duplicate or highly similar issues by analyzing titles, descriptions, and labels
|
||||
- Group related issues by theme, component, or subsystem
|
||||
- Cluster PRs by feature area or dependency relationships
|
||||
- Flag issues that may be addressing the same root cause
|
||||
- Use semantic similarity, not just exact matches
|
||||
|
||||
3. **Prioritization and Triage**:
|
||||
- Highlight items requiring immediate attention (blocking issues, failed CI, requested reviews)
|
||||
- Surface items awaiting your direct action (assigned to you, mentions, review requests)
|
||||
- Identify stale items that may need follow-up or closure
|
||||
- Note high-priority labels (P0, critical, security, etc.)
|
||||
|
||||
4. **Contextual Analysis**:
|
||||
- Summarize the current state of each PR (draft, ready for review, approved, changes requested)
|
||||
- Identify PRs with merge conflicts or failing checks
|
||||
- Note issues with recent activity spikes or community engagement
|
||||
- Flag dependency updates or security advisories
|
||||
|
||||
5. **Report Structure**:
|
||||
Your report must follow this format:
|
||||
|
||||
**MORNING GITHUB REPORT - [Date]**
|
||||
|
||||
**🚨 REQUIRES YOUR ATTENTION**
|
||||
- Items explicitly assigned to the user
|
||||
- Review requests awaiting user's approval
|
||||
- Mentions or direct questions
|
||||
- Blocking/critical issues
|
||||
|
||||
**📊 PULL REQUESTS ([count] open)**
|
||||
- Group by: Ready to Merge | In Review | Draft | Needs Work
|
||||
- For each PR: title, author, status, CI state, review count, age
|
||||
- Highlight conflicts or failed checks
|
||||
|
||||
**🐛 ISSUES ([count] open)**
|
||||
- Group by: Priority | Component | Theme
|
||||
- Mark potential duplicates clearly
|
||||
- Note new issues (created in last 24h)
|
||||
- Flag stale issues (no activity in 7+ days)
|
||||
|
||||
**📈 ACTIVITY SUMMARY**
|
||||
- New issues/PRs since yesterday
|
||||
- Recently closed items
|
||||
- Top contributors
|
||||
- Trending topics or labels
|
||||
|
||||
**💡 RECOMMENDED ACTIONS**
|
||||
- Specific next steps based on the data
|
||||
- Suggestions for cleanup (closing duplicates, merging ready PRs)
|
||||
- Items to follow up on
|
||||
|
||||
6. **Quality Standards**:
|
||||
- Use clear, scannable formatting with emojis for visual hierarchy
|
||||
- Include direct links to all referenced issues and PRs
|
||||
- Keep summaries concise but informative (1-2 sentences per item)
|
||||
- Use relative timestamps ("2 hours ago", "3 days old")
|
||||
- Highlight actionable items with clear CTAs
|
||||
|
||||
7. **Error Handling**:
|
||||
- If repository access fails, explicitly state which repos couldn't be accessed
|
||||
- If no issues/PRs exist, provide a positive "all clear" message
|
||||
- If rate limits are hit, show partial results with a warning
|
||||
- Always attempt to provide value even with incomplete data
|
||||
|
||||
8. **Adaptive Scope**:
|
||||
- If the user has access to multiple repositories, intelligently scope the report:
|
||||
- Default to repositories with recent activity
|
||||
- Allow user to specify repos if needed
|
||||
- Group multi-repo items by repository
|
||||
- Adjust detail level based on volume (more items = more concise summaries)
|
||||
|
||||
## Output Expectations
|
||||
|
||||
Your report should be:
|
||||
- **Comprehensive**: Cover all relevant activity without overwhelming detail
|
||||
- **Actionable**: Make it clear what needs attention and why
|
||||
- **Scannable**: Use formatting that allows quick visual parsing
|
||||
- **Contextual**: Provide enough background to make decisions
|
||||
- **Timely**: Focus on recent activity and current state
|
||||
|
||||
When you cannot find specific data, state this explicitly rather than omitting sections. If the user's query is ambiguous (e.g., which repositories to scan), ask for clarification before proceeding.
|
||||
|
||||
Always end with a summary line indicating the report's completeness (e.g., "Report complete: 3 repositories scanned, 12 issues, 5 PRs analyzed").
|
||||
@@ -0,0 +1,121 @@
|
||||
# Anti-Pattern Czar
|
||||
|
||||
You are the **Anti-Pattern Czar**, an expert at identifying and fixing error handling anti-patterns.
|
||||
|
||||
## Your Mission
|
||||
|
||||
Help the user systematically fix error handling anti-patterns detected by the automated scanner.
|
||||
|
||||
## Process
|
||||
|
||||
1. **Run the detector:**
|
||||
```bash
|
||||
bun run scripts/anti-pattern-test/detect-error-handling-antipatterns.ts
|
||||
```
|
||||
|
||||
2. **Analyze the results:**
|
||||
- Count CRITICAL, HIGH, MEDIUM, and APPROVED_OVERRIDE issues
|
||||
- Prioritize CRITICAL issues on critical paths first
|
||||
- Group similar patterns together
|
||||
|
||||
3. **For each CRITICAL issue:**
|
||||
|
||||
a. **Read the problematic code** using the Read tool
|
||||
|
||||
b. **Explain the problem:**
|
||||
- Why is this dangerous?
|
||||
- What debugging nightmare could this cause?
|
||||
- What specific error is being swallowed?
|
||||
|
||||
c. **Determine the right fix:**
|
||||
- **Option 1: Add proper logging** - If this is a real error that should be visible
|
||||
- **Option 2: Add [APPROVED OVERRIDE]** - If this is expected/documented behavior
|
||||
- **Option 3: Remove the try-catch entirely** - If the error should propagate
|
||||
- **Option 4: Add specific error type checking** - If only certain errors should be caught
|
||||
|
||||
d. **Propose the fix** and ask for approval
|
||||
|
||||
e. **Apply the fix** after approval
|
||||
|
||||
4. **Work through issues methodically:**
|
||||
- Fix one at a time
|
||||
- Re-run the detector after each batch of fixes
|
||||
- Track progress: "Fixed 3/28 critical issues"
|
||||
|
||||
## Guidelines for Approved Overrides
|
||||
|
||||
Only approve overrides when ALL of these are true:
|
||||
- The error is **expected and frequent** (e.g., JSON parse on optional fields)
|
||||
- Logging would create **too much noise** (high-frequency operations)
|
||||
- There's **explicit recovery logic** (fallback value, retry, graceful degradation)
|
||||
- The reason is **specific and technical** (not vague like "seems fine")
|
||||
|
||||
## Valid Override Examples:
|
||||
|
||||
✅ **GOOD:**
|
||||
- "Expected JSON parse failures for optional data fields, too frequent to log"
|
||||
- "Logger can't log its own failures, using stderr as last resort"
|
||||
- "Health check port scan, expected connection failures on free port detection"
|
||||
- "Git repo detection, expected failures when not in a git directory"
|
||||
|
||||
❌ **BAD:**
|
||||
- "Error is not important" (why catch it then?)
|
||||
- "Happens sometimes" (when? why?)
|
||||
- "Works fine without logging" (works until it doesn't)
|
||||
- "Optional" (optional errors still need visibility)
|
||||
|
||||
## Critical Path Rules
|
||||
|
||||
For files in the CRITICAL_PATHS list (SDKAgent.ts, GeminiAgent.ts, OpenRouterAgent.ts, SessionStore.ts, worker-service.ts):
|
||||
|
||||
- **NEVER** approve overrides on critical paths without exceptional justification
|
||||
- Errors on critical paths MUST be visible (logged) or fatal (thrown)
|
||||
- Catch-and-continue on critical paths is BANNED unless explicitly approved
|
||||
- If in doubt, make it throw - fail loud, not silent
|
||||
|
||||
## Output Format
|
||||
|
||||
After each fix:
|
||||
```
|
||||
✅ Fixed: src/utils/example.ts:42
|
||||
Pattern: NO_LOGGING_IN_CATCH
|
||||
Solution: Added logger.error() with context
|
||||
|
||||
Progress: 3/28 critical issues remaining
|
||||
```
|
||||
|
||||
After completing a batch:
|
||||
```
|
||||
🎯 Batch complete! Re-running detector...
|
||||
[shows new results]
|
||||
```
|
||||
|
||||
## Important
|
||||
|
||||
- **Read the code** before proposing fixes - understand what it's doing
|
||||
- **Ask the user** if you're uncertain about the right approach
|
||||
- **Don't blindly add overrides** - challenge each one
|
||||
- **Prefer logging** over overrides when in doubt
|
||||
- **Work incrementally** - small batches, frequent validation
|
||||
|
||||
## When Complete
|
||||
|
||||
Report final statistics:
|
||||
```
|
||||
🎉 Anti-pattern cleanup complete!
|
||||
|
||||
Before:
|
||||
🔴 CRITICAL: 28
|
||||
🟠 HIGH: 47
|
||||
🟡 MEDIUM: 76
|
||||
|
||||
After:
|
||||
🔴 CRITICAL: 0
|
||||
🟠 HIGH: 47
|
||||
🟡 MEDIUM: 76
|
||||
⚪ APPROVED OVERRIDES: 15
|
||||
|
||||
All critical anti-patterns resolved!
|
||||
```
|
||||
|
||||
Now, ask the user: "Ready to fix error handling anti-patterns? I'll start with the critical issues."
|
||||
@@ -0,0 +1,371 @@
|
||||
# Comprehensive Claude-Mem Installer with @clack/prompts
|
||||
|
||||
## Overview
|
||||
|
||||
Build a beautiful, animated CLI installer for claude-mem using `@clack/prompts` (v1.0.1). Distributable via `npx claude-mem-installer` and `curl -fsSL https://install.cmem.ai | bash`. Replaces the need for users to manually clone, build, configure settings, and start the worker.
|
||||
|
||||
**Worktree**: `feat/animated-installer` at `.claude/worktrees/animated-installer`
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: Documentation & API Reference
|
||||
|
||||
### Allowed APIs (@clack/prompts v1.0.1, ESM-only)
|
||||
|
||||
| API | Signature | Use Case |
|
||||
|-----|-----------|----------|
|
||||
| `intro(title?)` | `void` | Opening banner |
|
||||
| `outro(message?)` | `void` | Completion message |
|
||||
| `cancel(message?)` | `void` | User cancelled |
|
||||
| `isCancel(value)` | `boolean` | Check if user pressed Ctrl+C |
|
||||
| `text(opts)` | `Promise<string \| symbol>` | API key input, port, data dir |
|
||||
| `password(opts)` | `Promise<string \| symbol>` | API key input (masked) |
|
||||
| `select(opts)` | `Promise<Value \| symbol>` | Provider, model, auth method |
|
||||
| `multiselect(opts)` | `Promise<Value[] \| symbol>` | IDE selection, observation types |
|
||||
| `confirm(opts)` | `Promise<boolean \| symbol>` | Enable Chroma, start worker |
|
||||
| `spinner()` | `SpinnerResult` | Installing deps, building, starting worker |
|
||||
| `progress(opts)` | `ProgressResult` | Multi-step installation progress |
|
||||
| `tasks(tasks[])` | `Promise<void>` | Sequential install steps |
|
||||
| `group(prompts, opts)` | `Promise<Results>` | Chain prompts with shared results |
|
||||
| `note(message, title)` | `void` | Display settings summary, next steps |
|
||||
| `log.info/success/warn/error(msg)` | `void` | Status messages |
|
||||
| `box(message, title, opts)` | `void` | Welcome box, completion summary |
|
||||
|
||||
### Anti-Patterns
|
||||
- Do NOT use `require()` — package is ESM-only
|
||||
- Do NOT call prompts without TTY check first — hangs indefinitely in non-TTY
|
||||
- Do NOT forget `isCancel()` check after every prompt (or use `group()` with `onCancel`)
|
||||
- Do NOT use `chalk` — use `picocolors` (clack's dep) for consistency
|
||||
- `text()` has no numeric mode — validate manually for port numbers
|
||||
- `spinner.stop()` does not accept status codes — use `spinner.error()` for failures
|
||||
|
||||
### Distribution Patterns
|
||||
- **npx**: `package.json` `bin` field → `"./dist/index.js"`, file needs `#!/usr/bin/env node`
|
||||
- **curl|bash**: Shell bootstrap downloads JS, runs `node script.js` directly (preserves TTY)
|
||||
- **esbuild**: Bundle to single ESM file, `platform: 'node'`, `banner` for shebang
|
||||
|
||||
### Key Source Files to Reference
|
||||
- Settings defaults: `src/shared/SettingsDefaultsManager.ts` (lines 73-125)
|
||||
- Settings validation: `src/services/server/SettingsRoutes.ts`
|
||||
- Worker startup: `src/services/worker-service.ts` (lines 337-359)
|
||||
- Health check: `src/services/infrastructure/HealthMonitor.ts`
|
||||
- Plugin registration: `plugin/.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`
|
||||
- Marketplace sync: `scripts/sync-marketplace.cjs`
|
||||
- Cursor integration: `src/services/integrations/CursorHooksInstaller.ts`
|
||||
- Existing OpenClaw installer: `install/public/openclaw.sh` (reference for logic, not code to copy)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Project Scaffolding
|
||||
|
||||
**Goal**: Set up the installer package structure with build tooling.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **Create directory structure** in the worktree:
|
||||
```
|
||||
installer/
|
||||
├── src/
|
||||
│ ├── index.ts # Entry point with TTY guard
|
||||
│ ├── steps/
|
||||
│ │ ├── welcome.ts # intro + version check
|
||||
│ │ ├── dependencies.ts # bun, uv, git checks
|
||||
│ │ ├── ide-selection.ts # IDE picker + registration
|
||||
│ │ ├── provider.ts # AI provider + API key
|
||||
│ │ ├── settings.ts # Additional settings config
|
||||
│ │ ├── install.ts # Clone, build, register plugin
|
||||
│ │ ├── worker.ts # Start worker + health check
|
||||
│ │ └── complete.ts # Summary + next steps
|
||||
│ └── utils/
|
||||
│ ├── system.ts # OS detection, command runner
|
||||
│ ├── dependencies.ts # bun/uv/git install helpers
|
||||
│ └── settings-writer.ts # Write ~/.claude-mem/settings.json
|
||||
├── build.mjs # esbuild config
|
||||
├── package.json # bin, type: module, deps
|
||||
└── tsconfig.json
|
||||
```
|
||||
|
||||
2. **Create `package.json`**:
|
||||
```json
|
||||
{
|
||||
"name": "claude-mem-installer",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"bin": { "claude-mem-installer": "./dist/index.js" },
|
||||
"files": ["dist"],
|
||||
"scripts": {
|
||||
"build": "node build.mjs",
|
||||
"dev": "node build.mjs && node dist/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^1.0.1",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.24.0",
|
||||
"typescript": "^5.7.0",
|
||||
"@types/node": "^22.0.0"
|
||||
},
|
||||
"engines": { "node": ">=18.0.0" }
|
||||
}
|
||||
```
|
||||
|
||||
3. **Create `build.mjs`**:
|
||||
- esbuild bundle: `entryPoints: ['src/index.ts']`, `format: 'esm'`, `platform: 'node'`, `target: 'node18'`
|
||||
- Banner: `#!/usr/bin/env node`
|
||||
- Output: `dist/index.js`
|
||||
|
||||
4. **Create `tsconfig.json`**:
|
||||
- `module: "ESNext"`, `target: "ES2022"`, `moduleResolution: "bundler"`
|
||||
|
||||
5. **Run `npm install`** in installer/ directory
|
||||
|
||||
### Verification
|
||||
- [ ] `node build.mjs` succeeds
|
||||
- [ ] `dist/index.js` exists with shebang
|
||||
- [ ] `node dist/index.js` runs (even if empty installer)
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Entry Point + Welcome Screen
|
||||
|
||||
**Goal**: Create the main entry point with TTY detection and a beautiful welcome screen.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/index.ts`** — Entry point:
|
||||
- TTY guard: if `!process.stdin.isTTY`, print error directing user to `npx claude-mem-installer`, exit 1
|
||||
- Import and call `runInstaller()` from steps
|
||||
- Top-level catch → `p.cancel()` + exit 1
|
||||
|
||||
2. **`src/steps/welcome.ts`** — Welcome step:
|
||||
- `p.intro()` with styled title using picocolors: `" claude-mem installer "`
|
||||
- Display version info via `p.log.info()`
|
||||
- Check if already installed (detect `~/.claude-mem/settings.json` and `~/.claude/plugins/marketplaces/thedotmack/`)
|
||||
- If upgrade detected, `p.confirm()`: "claude-mem is already installed. Upgrade?"
|
||||
- `p.select()` for install mode: Fresh Install vs Upgrade vs Configure Only
|
||||
|
||||
3. **`src/utils/system.ts`** — System utilities:
|
||||
- `detectOS()`: returns 'macos' | 'linux' | 'windows'
|
||||
- `commandExists(cmd)`: checks if command is in PATH
|
||||
- `runCommand(cmd, args)`: executes shell command, returns { stdout, stderr, exitCode }
|
||||
- `expandHome(path)`: resolves `~` to home directory
|
||||
|
||||
### Verification
|
||||
- [ ] Running `node dist/index.js` shows intro banner
|
||||
- [ ] Ctrl+C triggers cancel message
|
||||
- [ ] Non-TTY (piped) shows error and exits
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Dependency Checks
|
||||
|
||||
**Goal**: Check and install required dependencies (Bun, uv, git, Node.js version).
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/steps/dependencies.ts`** — Dependency checker:
|
||||
- Use `p.tasks()` to check each dependency sequentially with animated spinners:
|
||||
- **Node.js**: Verify >= 18.0.0 via `process.version`
|
||||
- **git**: `commandExists('git')`, show install instructions per OS if missing
|
||||
- **Bun**: Check PATH + common locations (`~/.bun/bin/bun`, `/usr/local/bin/bun`, `/opt/homebrew/bin/bun`). Min version 1.1.14. Offer to auto-install from `https://bun.sh/install`
|
||||
- **uv**: Check PATH + common locations (`~/.local/bin/uv`, `~/.cargo/bin/uv`). Offer to auto-install from `https://astral.sh/uv/install.sh`
|
||||
- For missing deps: `p.confirm()` to auto-install, or show manual instructions
|
||||
- After install attempts, re-verify each dep
|
||||
|
||||
2. **`src/utils/dependencies.ts`** — Install helpers:
|
||||
- `installBun()`: downloads and runs bun install script
|
||||
- `installUv()`: downloads and runs uv install script
|
||||
- `findBinary(name, extraPaths[])`: searches PATH + known locations
|
||||
- `checkVersion(binary, minVersion)`: parses `--version` output
|
||||
|
||||
### Verification
|
||||
- [ ] Shows green checkmarks for found dependencies
|
||||
- [ ] Shows yellow warnings for missing deps with install option
|
||||
- [ ] Auto-install actually installs bun/uv when confirmed
|
||||
- [ ] Fails gracefully if git is missing (can't auto-install)
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: IDE Selection & Provider Configuration
|
||||
|
||||
**Goal**: Let user choose IDEs and configure AI provider with API keys.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/steps/ide-selection.ts`** — IDE picker:
|
||||
- `p.multiselect()` with options:
|
||||
- Claude Code (default selected, hint: "recommended")
|
||||
- Cursor
|
||||
- Windsurf (hint: "coming soon", disabled: true)
|
||||
- For Claude Code: explain plugin will be registered via marketplace
|
||||
- For Cursor: explain hooks will be installed via CursorHooksInstaller pattern
|
||||
- Store selections for later installation steps
|
||||
|
||||
2. **`src/steps/provider.ts`** — AI provider configuration:
|
||||
- `p.select()` for provider:
|
||||
- **Claude** (hint: "recommended — uses your Claude subscription")
|
||||
- **Gemini** (hint: "free tier available")
|
||||
- **OpenRouter** (hint: "free models available")
|
||||
- **If Claude selected**:
|
||||
- `p.select()` for auth method: "CLI (Max Plan subscription)" vs "API Key"
|
||||
- If API key: `p.password()` for key input
|
||||
- **If Gemini selected**:
|
||||
- `p.password()` for API key (required)
|
||||
- `p.select()` for model: gemini-2.5-flash-lite (default), gemini-2.5-flash, gemini-3-flash-preview
|
||||
- `p.confirm()` for rate limiting (default: true)
|
||||
- **If OpenRouter selected**:
|
||||
- `p.password()` for API key (required)
|
||||
- `p.text()` for model (default: `xiaomi/mimo-v2-flash:free`)
|
||||
- Validate API keys where possible (non-empty, format check)
|
||||
|
||||
### Verification
|
||||
- [ ] Multiselect allows picking multiple IDEs
|
||||
- [ ] Provider selection shows correct follow-up prompts
|
||||
- [ ] API keys are masked during input
|
||||
- [ ] Cancel at any step triggers graceful exit
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Settings Configuration
|
||||
|
||||
**Goal**: Configure additional settings with sensible defaults.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/steps/settings.ts`** — Settings wizard:
|
||||
- `p.confirm()`: "Use default settings?" (recommended) — if yes, skip detailed config
|
||||
- If customizing, use `p.group()` for:
|
||||
- **Worker port**: `p.text()` with default 37777, validate 1024-65535
|
||||
- **Data directory**: `p.text()` with default `~/.claude-mem`
|
||||
- **Context observations**: `p.text()` with default 50, validate 1-200
|
||||
- **Log level**: `p.select()` — DEBUG, INFO (default), WARN, ERROR
|
||||
- **Python version**: `p.text()` with default 3.13
|
||||
- **Chroma vector search**: `p.confirm()` (default: true)
|
||||
- If yes, `p.select()` mode: local (default) vs remote
|
||||
- If remote: `p.text()` for host, port, `p.confirm()` for SSL
|
||||
- Show settings summary via `p.note()` before proceeding
|
||||
|
||||
2. **`src/utils/settings-writer.ts`** — Write settings:
|
||||
- Build flat key-value settings object matching SettingsDefaultsManager schema
|
||||
- Merge with existing settings if upgrading (preserve user customizations)
|
||||
- Write to `~/.claude-mem/settings.json`
|
||||
- Create `~/.claude-mem/` directory if it doesn't exist
|
||||
|
||||
### Verification
|
||||
- [ ] Default settings mode skips all detailed prompts
|
||||
- [ ] Custom settings validates all inputs
|
||||
- [ ] Settings file written matches SettingsDefaultsManager schema exactly
|
||||
- [ ] Existing settings preserved on upgrade
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Installation Execution
|
||||
|
||||
**Goal**: Clone repo, build plugin, register with IDEs, start worker.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/steps/install.ts`** — Installation runner:
|
||||
- Use `p.tasks()` for visual progress:
|
||||
- **"Cloning claude-mem repository"**: `git clone --depth 1 https://github.com/thedotmack/claude-mem.git` to temp dir
|
||||
- **"Installing dependencies"**: `npm install` in cloned repo
|
||||
- **"Building plugin"**: `npm run build` in cloned repo
|
||||
- **"Registering plugin"**: Copy plugin files to `~/.claude/plugins/marketplaces/thedotmack/`
|
||||
- Create marketplace.json, plugin.json structure
|
||||
- Register in `~/.claude/plugins/known_marketplaces.json`
|
||||
- Add to `~/.claude/plugins/installed_plugins.json`
|
||||
- Enable in `~/.claude/settings.json` under `enabledPlugins`
|
||||
- **"Installing dependencies"** (in marketplace dir): `npm install`
|
||||
- For Cursor (if selected):
|
||||
- **"Configuring Cursor hooks"**: Run Cursor hooks installer logic
|
||||
- Write hooks.json to `~/.cursor/` or project-level `.cursor/`
|
||||
- Configure MCP in `.cursor/mcp.json`
|
||||
|
||||
2. **`src/steps/worker.ts`** — Worker startup:
|
||||
- Use `p.spinner()` for worker startup:
|
||||
- Start worker: `bun plugin/scripts/worker-service.cjs` (from marketplace dir)
|
||||
- Write PID file to `~/.claude-mem/worker.pid`
|
||||
- Two-stage health check (copy pattern from OpenClaw installer):
|
||||
- Stage 1: Poll `/api/health` — spinner message: "Starting worker service..."
|
||||
- Stage 2: Poll `/api/readiness` — spinner message: "Initializing database..."
|
||||
- Budget: 30 attempts, 1 second apart
|
||||
- On success: `spinner.stop("Worker running on port {port}")`
|
||||
- On failure: `spinner.error("Worker failed to start")`, show log path
|
||||
|
||||
### Verification
|
||||
- [ ] Plugin files exist at `~/.claude/plugins/marketplaces/thedotmack/`
|
||||
- [ ] known_marketplaces.json updated
|
||||
- [ ] installed_plugins.json updated
|
||||
- [ ] settings.json has enabledPlugins entry
|
||||
- [ ] Worker responds to `/api/health` with 200
|
||||
- [ ] Worker responds to `/api/readiness` with 200
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: Completion & Summary
|
||||
|
||||
**Goal**: Show success screen with configuration summary and next steps.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`src/steps/complete.ts`** — Completion screen:
|
||||
- `p.note()` with configuration summary:
|
||||
- Provider + model
|
||||
- IDEs configured
|
||||
- Data directory
|
||||
- Worker port
|
||||
- Chroma enabled/disabled
|
||||
- `p.note()` with next steps:
|
||||
- "Open Claude Code and start a conversation — memory is automatic!"
|
||||
- "View your memories: http://localhost:{port}"
|
||||
- "Search past work: use /mem-search in Claude Code"
|
||||
- If Cursor: "Open Cursor — hooks are active in your projects"
|
||||
- `p.outro()` with styled completion message
|
||||
|
||||
### Verification
|
||||
- [ ] Summary accurately reflects chosen settings
|
||||
- [ ] URLs use correct port from settings
|
||||
- [ ] Next steps are relevant to selected IDEs
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: curl|bash Bootstrap Script
|
||||
|
||||
**Goal**: Create the shell bootstrap script for `curl -fsSL https://install.cmem.ai | bash`.
|
||||
|
||||
### Tasks
|
||||
|
||||
1. **`install/public/install.sh`** — Bootstrap script:
|
||||
- Check for Node.js >= 18 (required to run the installer)
|
||||
- Download bundled installer JS to temp file
|
||||
- Execute with `node` directly (preserves TTY for @clack/prompts)
|
||||
- Cleanup temp file on exit (trap)
|
||||
- Support `--non-interactive` flag passthrough
|
||||
- Support `--provider=X --api-key=Y` flag passthrough
|
||||
|
||||
2. **Update `install/vercel.json`** to serve `install.sh` alongside `openclaw.sh`
|
||||
|
||||
### Verification
|
||||
- [ ] `curl -fsSL https://install.cmem.ai | bash` downloads and runs installer
|
||||
- [ ] Interactive prompts work after curl download
|
||||
- [ ] Temp file cleaned up on success and failure
|
||||
- [ ] Flags pass through correctly
|
||||
|
||||
---
|
||||
|
||||
## Phase 9: Final Verification
|
||||
|
||||
### Checks
|
||||
- [ ] `npm run build` in installer/ produces single-file `dist/index.js`
|
||||
- [ ] `node dist/index.js` runs full wizard flow
|
||||
- [ ] Fresh install on clean system works end-to-end
|
||||
- [ ] Upgrade path preserves existing settings
|
||||
- [ ] Ctrl+C at any step exits cleanly
|
||||
- [ ] Non-TTY shows error message
|
||||
- [ ] All settings written match SettingsDefaultsManager.ts defaults schema
|
||||
- [ ] Worker health check succeeds after install
|
||||
- [ ] Plugin appears in Claude Code plugin list
|
||||
- [ ] grep for deprecated/non-existent APIs returns 0 results
|
||||
- [ ] No `require()` calls in source (ESM-only)
|
||||
- [ ] No `chalk` imports (use picocolors)
|
||||
@@ -0,0 +1,290 @@
|
||||
# Test Quality Audit Report
|
||||
|
||||
**Date**: 2026-01-05
|
||||
**Auditor**: Claude Code (Opus 4.5)
|
||||
**Methodology**: Deep analysis with focus on anti-pattern prevention, actual functionality testing, and regression prevention
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Total Test Files Audited**: 41
|
||||
**Total Test Cases**: ~450+
|
||||
|
||||
### Score Distribution
|
||||
|
||||
| Score | Category | Count | Percentage |
|
||||
|-------|----------|-------|------------|
|
||||
| 5 | Essential | 8 | 19.5% |
|
||||
| 4 | Valuable | 15 | 36.6% |
|
||||
| 3 | Marginal | 11 | 26.8% |
|
||||
| 2 | Weak | 5 | 12.2% |
|
||||
| 1 | Delete | 2 | 4.9% |
|
||||
|
||||
### Key Findings
|
||||
|
||||
**Strengths**:
|
||||
- SQLite database tests are exemplary - real database operations with proper setup/teardown
|
||||
- Infrastructure tests (WMIC parsing, token calculator) use pure unit testing with no mocks
|
||||
- Search strategy tests have comprehensive coverage of edge cases
|
||||
- Logger formatTool tests are thorough and test actual transformation logic
|
||||
|
||||
**Critical Issues**:
|
||||
- **context-builder.test.ts** has incomplete mocks that pollute the module cache, causing 81 test failures when run with the full suite
|
||||
- Several tests verify mock behavior rather than actual functionality
|
||||
- Type validation tests (export-types.test.ts) provide minimal value - TypeScript already validates types at compile time
|
||||
- Some "validation" tests only verify code patterns exist, not that they work
|
||||
|
||||
**Recommendations**:
|
||||
1. Fix or delete context-builder.test.ts - it actively harms the test suite
|
||||
2. Delete trivial type validation tests that duplicate TypeScript compiler checks
|
||||
3. Convert heavy-mock tests to integration tests where feasible
|
||||
4. Add integration tests for critical paths (hook execution, worker API endpoints)
|
||||
|
||||
---
|
||||
|
||||
## Detailed Scores
|
||||
|
||||
### Score 5 - Essential (8 tests)
|
||||
|
||||
These tests catch real bugs, use minimal mocking, and test actual behavior.
|
||||
|
||||
| File | Test Count | Notes |
|
||||
|------|------------|-------|
|
||||
| `tests/sqlite/observations.test.ts` | 25+ | Real SQLite operations, in-memory DB, tests actual data persistence and retrieval |
|
||||
| `tests/sqlite/sessions.test.ts` | 20+ | Real database CRUD operations, status transitions, relationship integrity |
|
||||
| `tests/sqlite/transactions.test.ts` | 15+ | Critical transaction isolation tests, rollback behavior, error handling |
|
||||
| `tests/context/token-calculator.test.ts` | 35+ | Pure unit tests, no mocks, tests actual token estimation algorithms |
|
||||
| `tests/infrastructure/wmic-parsing.test.ts` | 20+ | Pure parsing logic tests, validates Windows process enumeration edge cases |
|
||||
| `tests/utils/logger-format-tool.test.ts` | 56 | Comprehensive formatTool tests, validates JSON parsing, tool output formatting |
|
||||
| `tests/server/server.test.ts` | 15+ | Real HTTP server integration tests, actual endpoint validation |
|
||||
| `tests/cursor-hook-outputs.test.ts` | 12+ | Integration tests running actual hook scripts, validates real output |
|
||||
|
||||
**Why Essential**: These tests catch actual bugs before production. They test real behavior with minimal abstraction. The SQLite tests in particular are exemplary - they use an in-memory database but perform real SQL operations.
|
||||
|
||||
---
|
||||
|
||||
### Score 4 - Valuable (15 tests)
|
||||
|
||||
Good tests with acceptable mocking that still verify meaningful behavior.
|
||||
|
||||
| File | Test Count | Notes |
|
||||
|------|------------|-------|
|
||||
| `tests/sqlite/prompts.test.ts` | 15+ | Real DB operations for user prompts, timestamp handling |
|
||||
| `tests/sqlite/summaries.test.ts` | 15+ | Real DB operations for session summaries |
|
||||
| `tests/worker/search/search-orchestrator.test.ts` | 30+ | Comprehensive strategy selection logic, good edge case coverage |
|
||||
| `tests/worker/search/strategies/sqlite-search-strategy.test.ts` | 25+ | Filter logic tests, date range handling |
|
||||
| `tests/worker/search/strategies/hybrid-search-strategy.test.ts` | 20+ | Ranking preservation, merge logic |
|
||||
| `tests/worker/search/strategies/chroma-search-strategy.test.ts` | 20+ | Vector search behavior, doc_type filtering |
|
||||
| `tests/worker/search/result-formatter.test.ts` | 15+ | Output formatting validation |
|
||||
| `tests/gemini_agent.test.ts` | 20+ | Multi-turn conversation flow, rate limiting fallback |
|
||||
| `tests/infrastructure/health-monitor.test.ts` | 15+ | Health check logic, threshold validation |
|
||||
| `tests/infrastructure/graceful-shutdown.test.ts` | 15+ | Shutdown sequence, timeout handling |
|
||||
| `tests/infrastructure/process-manager.test.ts` | 12+ | Process lifecycle management |
|
||||
| `tests/cursor-mcp-config.test.ts` | 10+ | MCP configuration generation validation |
|
||||
| `tests/cursor-hooks-json-utils.test.ts` | 8+ | JSON parsing utilities |
|
||||
| `tests/shared/settings-defaults-manager.test.ts` | 27 | Settings validation, migration logic |
|
||||
| `tests/context/formatters/markdown-formatter.test.ts` | 15+ | Markdown generation, terminology consistency |
|
||||
|
||||
**Why Valuable**: These tests have some mocking but still verify important business logic. The search strategy tests are particularly good at testing the decision-making logic for query routing.
|
||||
|
||||
---
|
||||
|
||||
### Score 3 - Marginal (11 tests)
|
||||
|
||||
Tests with moderate value, often too much mocking or testing obvious behavior.
|
||||
|
||||
| File | Test Count | Issues |
|
||||
|------|------------|--------|
|
||||
| `tests/worker/agents/observation-broadcaster.test.ts` | 15+ | Heavy mocking of SSE workers, tests mock behavior more than actual broadcasting |
|
||||
| `tests/worker/agents/fallback-error-handler.test.ts` | 10+ | Error message formatting tests, low complexity |
|
||||
| `tests/worker/agents/session-cleanup-helper.test.ts` | 10+ | Cleanup logic with mocked dependencies |
|
||||
| `tests/context/observation-compiler.test.ts` | 20+ | Mock database, tests query building not actual compilation |
|
||||
| `tests/server/error-handler.test.ts` | 8+ | Mock Express response, tests formatting only |
|
||||
| `tests/cursor-registry.test.ts` | 8+ | Registry pattern tests, low risk area |
|
||||
| `tests/cursor-context-update.test.ts` | 5+ | File format validation, could be stricter |
|
||||
| `tests/hook-constants.test.ts` | 5+ | Constant validation, low value |
|
||||
| `tests/session_store.test.ts` | 10+ | In-memory store tests, straightforward logic |
|
||||
| `tests/logger-coverage.test.ts` | 8+ | Coverage verification, not functionality |
|
||||
| `tests/scripts/smart-install.test.ts` | 25+ | Path array tests, replicates rather than imports logic |
|
||||
|
||||
**Why Marginal**: These tests provide some regression protection but either mock too heavily or test low-risk areas. The smart-install tests notably replicate the path arrays from the source file rather than testing the actual module.
|
||||
|
||||
---
|
||||
|
||||
### Score 2 - Weak (5 tests)
|
||||
|
||||
Tests that mostly verify mocks work or provide little value.
|
||||
|
||||
| File | Test Count | Issues |
|
||||
|------|------------|--------|
|
||||
| `tests/worker/agents/response-processor.test.ts` | 20+ | **Heavy mocking**: >50% setup is mock configuration. Tests verify mocks are called, not that XML parsing actually works |
|
||||
| `tests/session_id_refactor.test.ts` | 10+ | **Code pattern validation**: Tests that certain patterns exist in code, not that they work |
|
||||
| `tests/session_id_usage_validation.test.ts` | 5+ | **Static analysis as tests**: Reads files and checks for string patterns. Should be a lint rule, not a test |
|
||||
| `tests/validate_sql_update.test.ts` | 5+ | **One-time validation**: Validated a migration, no ongoing value |
|
||||
| `tests/worker-spawn.test.ts` | 5+ | **Trivial mocking**: Tests spawn config exists, doesn't test actual spawning |
|
||||
|
||||
**Why Weak**: These tests create false confidence. The response-processor tests in particular set up elaborate mocks and then verify those mocks were called - they don't verify actual XML parsing or database operations work correctly.
|
||||
|
||||
---
|
||||
|
||||
### Score 1 - Delete (2 tests)
|
||||
|
||||
Tests that actively harm the codebase or provide zero value.
|
||||
|
||||
| File | Test Count | Issues |
|
||||
|------|------------|--------|
|
||||
| `tests/context/context-builder.test.ts` | 20+ | **CRITICAL**: Incomplete logger mock pollutes module cache. Causes 81 test failures when run with full suite. Tests verify mocks, not actual context building |
|
||||
| `tests/scripts/export-types.test.ts` | 30+ | **Zero runtime value**: Tests TypeScript type definitions compile. TypeScript compiler already does this. These tests can literally never fail at runtime |
|
||||
|
||||
**Why Delete**:
|
||||
- **context-builder.test.ts**: This test is actively harmful. It imports the logger module with an incomplete mock (only 4 of 13+ methods mocked), and this polluted mock persists in Bun's module cache. When other tests run afterwards, they get the broken logger singleton. The test itself only verifies that mocked methods were called with expected arguments - it doesn't test actual context building logic.
|
||||
- **export-types.test.ts**: These tests instantiate TypeScript interfaces and verify properties exist. TypeScript already validates this at compile time. If a type definition is wrong, the code won't compile. These runtime tests add overhead without catching any bugs that TypeScript wouldn't already catch.
|
||||
|
||||
---
|
||||
|
||||
## Missing Test Coverage
|
||||
|
||||
### Critical Gaps
|
||||
|
||||
| Area | Risk | Current Coverage | Recommendation |
|
||||
|------|------|------------------|----------------|
|
||||
| **Hook execution E2E** | HIGH | None | Add integration tests that run hooks with real Claude Code SDK |
|
||||
| **Worker API endpoints** | HIGH | Partial (server.test.ts) | Add tests for all REST endpoints: `/observe`, `/search`, `/health` |
|
||||
| **Chroma vector sync** | HIGH | None | Add tests for ChromaSync.ts embedding generation and retrieval |
|
||||
| **Database migrations** | MEDIUM | None | Add tests for schema migrations, especially version upgrades |
|
||||
| **Settings file I/O** | MEDIUM | Partial | Add tests for settings file creation, corruption recovery |
|
||||
| **Tag stripping** | MEDIUM | None | Add tests for `<private>` and `<meta-observation>` tag handling |
|
||||
| **MCP tool handlers** | MEDIUM | None | Add tests for search, timeline, get_observations MCP tools |
|
||||
| **Error recovery** | MEDIUM | Minimal | Add tests for worker crash recovery, database corruption handling |
|
||||
|
||||
### Recommended New Tests
|
||||
|
||||
1. **`tests/integration/hook-execution.test.ts`**
|
||||
- Run actual hooks with mocked Claude Code environment
|
||||
- Verify data flows correctly through SessionStart -> PostToolUse -> SessionEnd
|
||||
|
||||
2. **`tests/integration/worker-api.test.ts`**
|
||||
- Start actual worker server
|
||||
- Make real HTTP requests to all endpoints
|
||||
- Verify response formats and error handling
|
||||
|
||||
3. **`tests/services/chroma-sync.test.ts`**
|
||||
- Test embedding generation with real text
|
||||
- Test semantic similarity retrieval
|
||||
- Test sync between SQLite and Chroma
|
||||
|
||||
4. **`tests/utils/tag-stripping.test.ts`**
|
||||
- Test `<private>` tag removal
|
||||
- Test `<meta-observation>` tag handling
|
||||
- Test nested tag scenarios
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate Actions
|
||||
|
||||
1. **Delete or fix `tests/context/context-builder.test.ts`** (Priority: CRITICAL)
|
||||
- This test causes 81 other tests to fail due to module cache pollution
|
||||
- Either complete the logger mock (all 13+ methods) or delete entirely
|
||||
- Recommended: Delete and rewrite as integration test without mocks
|
||||
|
||||
2. **Delete `tests/scripts/export-types.test.ts`** (Priority: HIGH)
|
||||
- Zero runtime value - TypeScript compiler already validates types
|
||||
- Remove to reduce test suite noise
|
||||
|
||||
3. **Delete or convert validation tests** (Priority: MEDIUM)
|
||||
- `tests/session_id_refactor.test.ts` - Was useful during migration, no longer needed
|
||||
- `tests/session_id_usage_validation.test.ts` - Convert to lint rule
|
||||
- `tests/validate_sql_update.test.ts` - Was useful during migration, no longer needed
|
||||
|
||||
### Architecture Improvements
|
||||
|
||||
1. **Create test utilities for common mocks**
|
||||
- Centralize logger mock in `tests/utils/mock-logger.ts` with ALL methods
|
||||
- Centralize database mock with proper transaction support
|
||||
- Prevent incomplete mocks from polluting module cache
|
||||
|
||||
2. **Add integration test suite**
|
||||
- Create `tests/integration/` directory
|
||||
- Run with real worker server (separate database)
|
||||
- Test actual data flow, not mock interactions
|
||||
|
||||
3. **Implement test isolation**
|
||||
- Use `beforeEach` to reset module state
|
||||
- Consider test file ordering to prevent cache pollution
|
||||
- Add cleanup hooks for database state
|
||||
|
||||
### Quality Guidelines
|
||||
|
||||
For future tests, follow these principles:
|
||||
|
||||
1. **Prefer real implementations over mocks**
|
||||
- Use in-memory SQLite instead of mock database
|
||||
- Use real HTTP requests instead of mock req/res
|
||||
- Mock only external services (AI APIs, file system when needed)
|
||||
|
||||
2. **Test behavior, not implementation**
|
||||
- Bad: "verify function X was called with argument Y"
|
||||
- Good: "verify output contains expected data after operation"
|
||||
|
||||
3. **Each test should be able to fail**
|
||||
- If a test cannot fail (like type validation tests), it's not testing anything
|
||||
- Write tests that would catch real bugs
|
||||
|
||||
4. **Keep test setup minimal**
|
||||
- If >50% of test is mock setup, consider integration testing
|
||||
- Complex mock setup often indicates testing the wrong thing
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Full Test File Inventory
|
||||
|
||||
| File | Score | Tests | LOC | Mock % |
|
||||
|------|-------|-------|-----|--------|
|
||||
| `tests/context/context-builder.test.ts` | 1 | 20+ | 400+ | 80% |
|
||||
| `tests/context/formatters/markdown-formatter.test.ts` | 4 | 15+ | 200+ | 10% |
|
||||
| `tests/context/observation-compiler.test.ts` | 3 | 20+ | 300+ | 60% |
|
||||
| `tests/context/token-calculator.test.ts` | 5 | 35+ | 400+ | 0% |
|
||||
| `tests/cursor-context-update.test.ts` | 3 | 5+ | 100+ | 20% |
|
||||
| `tests/cursor-hook-outputs.test.ts` | 5 | 12+ | 250+ | 10% |
|
||||
| `tests/cursor-hooks-json-utils.test.ts` | 4 | 8+ | 150+ | 0% |
|
||||
| `tests/cursor-mcp-config.test.ts` | 4 | 10+ | 200+ | 20% |
|
||||
| `tests/cursor-registry.test.ts` | 3 | 8+ | 150+ | 30% |
|
||||
| `tests/gemini_agent.test.ts` | 4 | 20+ | 400+ | 40% |
|
||||
| `tests/hook-constants.test.ts` | 3 | 5+ | 80+ | 0% |
|
||||
| `tests/infrastructure/graceful-shutdown.test.ts` | 4 | 15+ | 300+ | 40% |
|
||||
| `tests/infrastructure/health-monitor.test.ts` | 4 | 15+ | 250+ | 30% |
|
||||
| `tests/infrastructure/process-manager.test.ts` | 4 | 12+ | 200+ | 35% |
|
||||
| `tests/infrastructure/wmic-parsing.test.ts` | 5 | 20+ | 240+ | 0% |
|
||||
| `tests/logger-coverage.test.ts` | 3 | 8+ | 150+ | 20% |
|
||||
| `tests/scripts/export-types.test.ts` | 1 | 30+ | 350+ | 0% |
|
||||
| `tests/scripts/smart-install.test.ts` | 3 | 25+ | 230+ | 0% |
|
||||
| `tests/server/error-handler.test.ts` | 3 | 8+ | 150+ | 50% |
|
||||
| `tests/server/server.test.ts` | 5 | 15+ | 300+ | 20% |
|
||||
| `tests/session_id_refactor.test.ts` | 2 | 10+ | 200+ | N/A |
|
||||
| `tests/session_id_usage_validation.test.ts` | 2 | 5+ | 150+ | N/A |
|
||||
| `tests/session_store.test.ts` | 3 | 10+ | 180+ | 10% |
|
||||
| `tests/shared/settings-defaults-manager.test.ts` | 4 | 27 | 400+ | 20% |
|
||||
| `tests/sqlite/observations.test.ts` | 5 | 25+ | 400+ | 0% |
|
||||
| `tests/sqlite/prompts.test.ts` | 4 | 15+ | 250+ | 0% |
|
||||
| `tests/sqlite/sessions.test.ts` | 5 | 20+ | 350+ | 0% |
|
||||
| `tests/sqlite/summaries.test.ts` | 4 | 15+ | 250+ | 0% |
|
||||
| `tests/sqlite/transactions.test.ts` | 5 | 15+ | 300+ | 0% |
|
||||
| `tests/utils/logger-format-tool.test.ts` | 5 | 56 | 1000+ | 0% |
|
||||
| `tests/validate_sql_update.test.ts` | 2 | 5+ | 100+ | N/A |
|
||||
| `tests/worker/agents/fallback-error-handler.test.ts` | 3 | 10+ | 200+ | 40% |
|
||||
| `tests/worker/agents/observation-broadcaster.test.ts` | 3 | 15+ | 350+ | 60% |
|
||||
| `tests/worker/agents/response-processor.test.ts` | 2 | 20+ | 500+ | 70% |
|
||||
| `tests/worker/agents/session-cleanup-helper.test.ts` | 3 | 10+ | 200+ | 50% |
|
||||
| `tests/worker/search/result-formatter.test.ts` | 4 | 15+ | 250+ | 20% |
|
||||
| `tests/worker/search/search-orchestrator.test.ts` | 4 | 30+ | 500+ | 45% |
|
||||
| `tests/worker/search/strategies/chroma-search-strategy.test.ts` | 4 | 20+ | 350+ | 50% |
|
||||
| `tests/worker/search/strategies/hybrid-search-strategy.test.ts` | 4 | 20+ | 300+ | 45% |
|
||||
| `tests/worker/search/strategies/sqlite-search-strategy.test.ts` | 4 | 25+ | 350+ | 40% |
|
||||
| `tests/worker-spawn.test.ts` | 2 | 5+ | 100+ | 60% |
|
||||
|
||||
---
|
||||
|
||||
*Report generated by Claude Code (Opus 4.5) on 2026-01-05*
|
||||
@@ -26,4 +26,4 @@ Manages semantic versioning for the claude-mem project itself. Handles updating
|
||||
## Adding New Skills
|
||||
|
||||
**For claude-mem development** → Add to `.claude/skills/`
|
||||
**For end users** → Add to `plugin/skills/` (gets distributed with plugin)
|
||||
**For end users** → Add to `plugin/skills/` (gets distributed with plugin)
|
||||
@@ -1,80 +0,0 @@
|
||||
---
|
||||
name: version-bump
|
||||
description: Manage semantic version updates for claude-mem project. Handles patch, minor, and major version increments following semantic versioning. Updates package.json, marketplace.json, and plugin.json. Creates git tags and GitHub releases. Auto-generates CHANGELOG.md from releases.
|
||||
---
|
||||
|
||||
# Version Bump Skill
|
||||
|
||||
**IMPORTANT:** You must first ultrathink and write detailed release notes before starting the version bump workflow.
|
||||
|
||||
## Version Types
|
||||
|
||||
- **PATCH** (x.y.Z): Bug fixes only
|
||||
- **MINOR** (x.Y.0): New features, backward compatible
|
||||
- **MAJOR** (X.0.0): Breaking changes
|
||||
|
||||
## Files to Update (ALL THREE)
|
||||
|
||||
1. `package.json` (line 3)
|
||||
2. `.claude-plugin/marketplace.json` (line 13)
|
||||
3. `plugin/.claude-plugin/plugin.json` (line 3)
|
||||
|
||||
## Workflow
|
||||
|
||||
```bash
|
||||
# 1. Check current version
|
||||
grep '"version"' package.json .claude-plugin/marketplace.json plugin/.claude-plugin/plugin.json
|
||||
|
||||
# 2. Update all 3 files to new version (use Edit tool)
|
||||
|
||||
# 3. Verify consistency
|
||||
grep '"version"' package.json .claude-plugin/marketplace.json plugin/.claude-plugin/plugin.json
|
||||
|
||||
# 4. Build
|
||||
npm run build
|
||||
|
||||
# 5. Commit version files
|
||||
git add package.json .claude-plugin/marketplace.json plugin/.claude-plugin/plugin.json
|
||||
git commit -m "chore: bump version to X.Y.Z"
|
||||
|
||||
# 6. Create tag
|
||||
git tag -a vX.Y.Z -m "Version X.Y.Z"
|
||||
|
||||
# 7. Push
|
||||
git push origin main && git push origin vX.Y.Z
|
||||
|
||||
# 8. Create GitHub release (use your detailed release notes here)
|
||||
gh release create vX.Y.Z --title "vX.Y.Z" --notes "RELEASE_NOTES_HERE"
|
||||
|
||||
# 9. Generate CHANGELOG.md from releases
|
||||
gh api repos/thedotmack/claude-mem/releases --paginate | node -e "
|
||||
const releases = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
||||
const lines = ['# Changelog', '', 'All notable changes to claude-mem.', ''];
|
||||
releases.slice(0, 50).forEach(r => {
|
||||
const date = r.published_at.split('T')[0];
|
||||
lines.push('## [' + r.tag_name + '] - ' + date);
|
||||
lines.push('');
|
||||
if (r.body) lines.push(r.body.trim());
|
||||
lines.push('');
|
||||
});
|
||||
console.log(lines.join('\n'));
|
||||
" > CHANGELOG.md
|
||||
|
||||
# 10. Commit CHANGELOG
|
||||
git add CHANGELOG.md
|
||||
git commit -m "docs: update CHANGELOG.md for vX.Y.Z"
|
||||
git push origin main
|
||||
|
||||
# 11. Discord notification
|
||||
npm run discord:notify vX.Y.Z
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Ultrathink + write detailed release notes
|
||||
- [ ] All 3 files have matching version
|
||||
- [ ] `npm run build` succeeds
|
||||
- [ ] Git tag created (vX.Y.Z format)
|
||||
- [ ] GitHub release created with detailed notes
|
||||
- [ ] CHANGELOG.md updated
|
||||
- [ ] Discord notification sent (if webhook configured)
|
||||
@@ -7,6 +7,12 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Before submitting
|
||||
|
||||
- [ ] I searched [existing issues](https://github.com/thedotmack/claude-mem/issues) and confirmed this is not a duplicate
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Quick Bug Report (Recommended)
|
||||
|
||||
**Use the automated bug report generator** for comprehensive diagnostics:
|
||||
|
||||
@@ -7,6 +7,12 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Before submitting
|
||||
|
||||
- [ ] I searched [existing issues](https://github.com/thedotmack/claude-mem/issues) and confirmed this is not a duplicate
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
actions: read # Required for Claude to read CI results on PRs
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
steps:
|
||||
- name: Get issue details and create discussion
|
||||
id: discussion
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
// Get issue details
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
}
|
||||
|
||||
- name: Comment on issue
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const issueNumber = ${{ steps.discussion.outputs.issue_number }};
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
console.log(`Added comment to issue #${issueNumber}`);
|
||||
|
||||
- name: Close and lock issue
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const issueNumber = ${{ steps.discussion.outputs.issue_number }};
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Deploy Install Scripts
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'openclaw/install.sh'
|
||||
- 'install/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Copy install scripts to deploy directory
|
||||
run: |
|
||||
mkdir -p install/public
|
||||
cp openclaw/install.sh install/public/openclaw.sh
|
||||
|
||||
- name: Deploy to Vercel
|
||||
uses: amondnet/vercel-action@v25
|
||||
with:
|
||||
vercel-token: ${{ secrets.VERCEL_TOKEN }}
|
||||
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
|
||||
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
|
||||
vercel-args: '--prod'
|
||||
working-directory: ./install
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm install --ignore-scripts
|
||||
- run: npm run build
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -14,11 +14,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run AI inference
|
||||
id: inference
|
||||
uses: actions/ai-inference@v1
|
||||
uses: actions/ai-inference@v2
|
||||
with:
|
||||
prompt: |
|
||||
Summarize the following GitHub issue in one paragraph:
|
||||
|
||||
+16
-1
@@ -9,16 +9,31 @@ dist/
|
||||
*.temp
|
||||
.install-version
|
||||
.claude/settings.local.json
|
||||
.claude/agents/
|
||||
.claude/skills/
|
||||
.claude/plans/
|
||||
.claude/worktrees/
|
||||
plugin/data/
|
||||
plugin/data.backup/
|
||||
package-lock.json
|
||||
bun.lock
|
||||
private/
|
||||
datasets/
|
||||
Auto Run Docs/
|
||||
|
||||
# Generated UI files (built from viewer-template.html)
|
||||
src/ui/viewer.html
|
||||
|
||||
# Local MCP server config (for development only)
|
||||
.mcp.json
|
||||
.cursor/
|
||||
.cursor/
|
||||
|
||||
# Prevent literal tilde directories (path validation bug artifacts)
|
||||
~*/
|
||||
|
||||
# Prevent other malformed path directories
|
||||
http*/
|
||||
https*/
|
||||
|
||||
# Ignore WebStorm project files (for dinosaur IDE users)
|
||||
.idea/
|
||||
|
||||
+896
-827
File diff suppressed because it is too large
Load Diff
@@ -19,10 +19,7 @@ Claude-mem is a Claude Code plugin providing persistent memory across sessions.
|
||||
**Viewer UI** (`src/ui/viewer/`) - React interface at http://localhost:37777, built to `plugin/ui/viewer.html`
|
||||
|
||||
## Privacy Tags
|
||||
|
||||
**Dual-Tag System** for meta-observation control:
|
||||
- `<private>content</private>` - User-level privacy control (manual, prevents storage)
|
||||
- `<claude-mem-context>content</claude-mem-context>` - System-level tag (auto-injected observations, prevents recursive storage)
|
||||
|
||||
**Implementation**: Tag stripping happens at hook layer (edge processing) before data reaches worker/database. See `src/utils/tag-stripping.ts` for shared utilities.
|
||||
|
||||
@@ -44,6 +41,18 @@ Settings are managed in `~/.claude-mem/settings.json`. The file is auto-created
|
||||
- **Database**: `~/.claude-mem/claude-mem.db`
|
||||
- **Chroma**: `~/.claude-mem/chroma/`
|
||||
|
||||
## Exit Code Strategy
|
||||
|
||||
Claude-mem hooks use specific exit codes per Claude Code's hook contract:
|
||||
|
||||
- **Exit 0**: Success or graceful shutdown (Windows Terminal closes tabs)
|
||||
- **Exit 1**: Non-blocking error (stderr shown to user, continues)
|
||||
- **Exit 2**: Blocking error (stderr fed to Claude for processing)
|
||||
|
||||
**Philosophy**: Worker/hook errors exit with code 0 to prevent Windows Terminal tab accumulation. The wrapper/plugin layer handles restart logic. ERROR-level logging is maintained for diagnostics.
|
||||
|
||||
See `private/context/claude-code/exit-codes.md` for full hook behavior matrix.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Bun** (all platforms - auto-installed if missing)
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
# Monolith Refactor Report
|
||||
|
||||
> **Last Updated:** 2026-01-03 (post session-logging merge)
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The claude-mem codebase contains **~21,000 lines** of TypeScript across 71+ files. Analysis reveals several monolithic files that violate single-responsibility principles and create tight coupling. This report identifies refactoring targets and proposes a modular architecture.
|
||||
|
||||
**Recent Changes:** The `session-logging` branch merge improved error handling across the codebase. SearchManager was reduced by ~180 lines, but SessionStore grew by ~110 lines due to new migrations and logging.
|
||||
|
||||
---
|
||||
|
||||
## Part 1: Monolith Files Identified
|
||||
|
||||
### Critical Priority (>1500 lines)
|
||||
|
||||
| File | Lines | Methods | Primary Issues | Trend |
|
||||
|------|-------|---------|----------------|-------|
|
||||
| `src/services/worker-service.ts` | 2,034 | - | Server init, process management, Cursor hooks, MCP setup all mixed | ↓ -28 |
|
||||
| `src/services/sqlite/SessionStore.ts` | 2,011 | 49 | Migrations + CRUD + queries + transformations all in one class | ↑ +108 |
|
||||
| `src/services/worker/SearchManager.ts` | 1,778 | 17 | Three search strategies crammed together, formatting mixed in | ↓ -178 |
|
||||
|
||||
### High Priority (500-1500 lines)
|
||||
|
||||
| File | Lines | Issues | Trend |
|
||||
|------|-------|--------|-------|
|
||||
| `src/services/sync/ChromaSync.ts` | 870 | Sync and query operations mixed | — |
|
||||
| `src/services/context-generator.ts` | 659 | 23 standalone functions, no class structure | — |
|
||||
| `src/services/worker/http/routes/SessionRoutes.ts` | 625 | Provider selection mixed with business logic | ↑ +7 |
|
||||
| `src/services/worker/OpenRouterAgent.ts` | 599 | 80% code duplicated from other agents | ↓ -15 |
|
||||
| `src/services/worker/GeminiAgent.ts` | 574 | 80% code duplicated from other agents | ↓ -15 |
|
||||
| `src/services/worker/SDKAgent.ts` | 546 | Base patterns duplicated across all agents | ↓ -15 |
|
||||
| `src/services/sqlite/SessionSearch.ts` | 526 | FTS5 tables maintained for backward compat | — |
|
||||
| `src/services/sqlite/migrations.ts` | 509 | All 11 migrations in single file | — |
|
||||
| `src/services/sqlite/PendingMessageStore.ts` | 447 | Message queue operations | ↑ +21 |
|
||||
| `src/services/worker/http/routes/SettingsRoutes.ts` | 414 | File I/O, validation, git ops mixed | — |
|
||||
|
||||
### Code Duplication Issue
|
||||
|
||||
The three agent files (`SDKAgent`, `GeminiAgent`, `OpenRouterAgent`) share ~80% duplicate code:
|
||||
- Message building logic
|
||||
- Result parsing
|
||||
- Context updating
|
||||
- Database sync patterns
|
||||
|
||||
---
|
||||
|
||||
## Part 2: System Breakdown Proposal
|
||||
|
||||
### Domain-Based Module Architecture
|
||||
|
||||
```
|
||||
src/
|
||||
├── domains/ # Business domain modules
|
||||
│ ├── sessions/ # Session lifecycle
|
||||
│ │ ├── SessionRepository.ts
|
||||
│ │ ├── SessionService.ts
|
||||
│ │ └── types.ts
|
||||
│ │
|
||||
│ ├── observations/ # Observation management
|
||||
│ │ ├── ObservationRepository.ts
|
||||
│ │ ├── ObservationService.ts
|
||||
│ │ └── types.ts
|
||||
│ │
|
||||
│ ├── summaries/ # Summary generation
|
||||
│ │ ├── SummaryRepository.ts
|
||||
│ │ ├── SummaryService.ts
|
||||
│ │ └── types.ts
|
||||
│ │
|
||||
│ ├── prompts/ # Prompt storage
|
||||
│ │ ├── PromptRepository.ts
|
||||
│ │ └── types.ts
|
||||
│ │
|
||||
│ └── search/ # Search subsystem
|
||||
│ ├── strategies/
|
||||
│ │ ├── ChromaSearchStrategy.ts
|
||||
│ │ ├── FilterSearchStrategy.ts
|
||||
│ │ └── SearchStrategy.ts (interface)
|
||||
│ ├── SearchOrchestrator.ts
|
||||
│ ├── ResultFormatter.ts
|
||||
│ └── TimelineBuilder.ts
|
||||
│
|
||||
├── infrastructure/ # Cross-cutting infrastructure
|
||||
│ ├── database/
|
||||
│ │ ├── DatabaseConnection.ts
|
||||
│ │ ├── TransactionManager.ts
|
||||
│ │ └── migrations/
|
||||
│ │ ├── MigrationRunner.ts
|
||||
│ │ ├── 001_initial.ts
|
||||
│ │ ├── 002_add_prompts.ts
|
||||
│ │ └── ...
|
||||
│ │
|
||||
│ ├── vector/
|
||||
│ │ ├── ChromaClient.ts
|
||||
│ │ ├── ChromaSyncManager.ts
|
||||
│ │ └── ChromaQueryEngine.ts
|
||||
│ │
|
||||
│ └── agents/
|
||||
│ ├── BaseAgent.ts # Shared agent logic
|
||||
│ ├── AgentFactory.ts
|
||||
│ ├── MessageBuilder.ts
|
||||
│ ├── ResponseParser.ts
|
||||
│ ├── providers/
|
||||
│ │ ├── ClaudeProvider.ts
|
||||
│ │ ├── GeminiProvider.ts
|
||||
│ │ └── OpenRouterProvider.ts
|
||||
│ └── types.ts
|
||||
│
|
||||
├── api/ # HTTP layer
|
||||
│ ├── routes/
|
||||
│ │ ├── sessions.ts
|
||||
│ │ ├── data.ts
|
||||
│ │ ├── search.ts
|
||||
│ │ ├── settings.ts
|
||||
│ │ └── viewer.ts
|
||||
│ ├── middleware/
|
||||
│ └── server.ts
|
||||
│
|
||||
├── context/ # Context injection
|
||||
│ ├── ContextBuilder.ts
|
||||
│ ├── ContextConfigLoader.ts
|
||||
│ ├── ObservationCompiler.ts
|
||||
│ └── TokenCalculator.ts
|
||||
│
|
||||
└── shared/ # Shared utilities (existing)
|
||||
├── logger.ts
|
||||
├── settings.ts
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 3: Refactoring Targets by Priority
|
||||
|
||||
### Phase 1: Database Layer Decomposition
|
||||
|
||||
**Target:** `src/services/sqlite/SessionStore.ts` (2,011 lines, 49 methods → ~5 files)
|
||||
|
||||
| Extract To | Responsibility | Est. Lines |
|
||||
|------------|---------------|------------|
|
||||
| `domains/sessions/SessionRepository.ts` | Session CRUD ops | ~300 |
|
||||
| `domains/observations/ObservationRepository.ts` | Observation storage/retrieval | ~400 |
|
||||
| `domains/summaries/SummaryRepository.ts` | Summary storage/retrieval | ~200 |
|
||||
| `infrastructure/database/migrations/MigrationRunner.ts` | Schema migrations | ~250 |
|
||||
|
||||
**Benefits:**
|
||||
- Single responsibility per file
|
||||
- Testable in isolation
|
||||
- Reduces coupling
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: Agent Consolidation
|
||||
|
||||
**Target:** 3 agent files (1,719 lines → ~800 lines total)
|
||||
|
||||
| Extract To | Responsibility |
|
||||
|------------|---------------|
|
||||
| `infrastructure/agents/BaseAgent.ts` | Common agent logic, prompt building |
|
||||
| `infrastructure/agents/MessageBuilder.ts` | Message construction |
|
||||
| `infrastructure/agents/ResponseParser.ts` | Result parsing (observations, summaries) |
|
||||
| `infrastructure/agents/providers/*.ts` | Provider-specific API calls only |
|
||||
|
||||
**Benefits:**
|
||||
- Eliminates 80% code duplication
|
||||
- Easy to add new providers
|
||||
- Centralized message format changes
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: Search Strategy Pattern
|
||||
|
||||
**Target:** `src/services/worker/SearchManager.ts` (1,778 lines → ~5 files)
|
||||
|
||||
| Extract To | Responsibility |
|
||||
|------------|---------------|
|
||||
| `domains/search/SearchOrchestrator.ts` | Coordinates search strategies |
|
||||
| `domains/search/strategies/ChromaSearchStrategy.ts` | Vector search via Chroma |
|
||||
| `domains/search/strategies/FilterSearchStrategy.ts` | SQLite filter-based search |
|
||||
| `domains/search/ResultFormatter.ts` | Formats search results |
|
||||
| `domains/search/TimelineBuilder.ts` | Constructs timeline views |
|
||||
|
||||
**Benefits:**
|
||||
- Strategy pattern for extensibility
|
||||
- Clear fallback logic
|
||||
- Testable strategies
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: Context Generator Restructure
|
||||
|
||||
**Target:** `src/services/context-generator.ts` (659 lines → ~4 files)
|
||||
|
||||
| Extract To | Responsibility |
|
||||
|------------|---------------|
|
||||
| `context/ContextBuilder.ts` | Main builder class |
|
||||
| `context/ContextConfigLoader.ts` | Config loading/validation |
|
||||
| `context/ObservationCompiler.ts` | Compiles observations for injection |
|
||||
| `context/TokenCalculator.ts` | Token budget calculations |
|
||||
|
||||
**Benefits:**
|
||||
- Class-based structure
|
||||
- Clear dependencies
|
||||
- Easier testing
|
||||
|
||||
---
|
||||
|
||||
### Phase 5: Server/Infrastructure Split
|
||||
|
||||
**Target:** `src/services/worker-service.ts` (2,034 lines → ~4 files)
|
||||
|
||||
| Extract To | Responsibility |
|
||||
|------------|---------------|
|
||||
| `api/server.ts` | Express app, route registration |
|
||||
| `infrastructure/ProcessManager.ts` | PID files, signal handlers |
|
||||
| `infrastructure/CursorHooksInstaller.ts` | Cursor integration |
|
||||
| `infrastructure/MCPClientManager.ts` | MCP client lifecycle |
|
||||
|
||||
---
|
||||
|
||||
## Part 4: Dependency Reduction Strategy
|
||||
|
||||
### Current Pain Points
|
||||
|
||||
1. **SessionStore** imported by 7+ files directly
|
||||
2. No abstraction between routes and data access
|
||||
3. All routes depend on `DatabaseManager` which exposes raw `SessionStore`
|
||||
|
||||
### Proposed Dependency Injection
|
||||
|
||||
```typescript
|
||||
// infrastructure/container.ts
|
||||
export interface ServiceContainer {
|
||||
sessions: SessionService;
|
||||
observations: ObservationService;
|
||||
summaries: SummaryService;
|
||||
search: SearchOrchestrator;
|
||||
agents: AgentFactory;
|
||||
}
|
||||
|
||||
// Usage in routes
|
||||
app.post('/sessions', (req, res) => {
|
||||
const { sessions } = getContainer();
|
||||
sessions.create(req.body);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 5: Migration Strategy
|
||||
|
||||
### Incremental Approach
|
||||
|
||||
Each phase can be done independently without breaking the system:
|
||||
|
||||
1. **Create new modules** alongside existing code
|
||||
2. **Migrate routes one at a time** to use new modules
|
||||
3. **Deprecate old code** once all routes migrated
|
||||
4. **Remove deprecated code** after testing
|
||||
|
||||
### Testing Requirements
|
||||
|
||||
- Unit tests for each extracted module
|
||||
- Integration tests for repository operations
|
||||
- End-to-end tests for API routes
|
||||
|
||||
---
|
||||
|
||||
## Appendix: File Size Distribution
|
||||
|
||||
```
|
||||
2,034 src/services/worker-service.ts ████████████████████
|
||||
2,011 src/services/sqlite/SessionStore.ts ████████████████████
|
||||
1,778 src/services/worker/SearchManager.ts █████████████████
|
||||
870 src/services/sync/ChromaSync.ts ████████
|
||||
659 src/services/context-generator.ts ██████
|
||||
625 src/services/worker/http/routes/SessionRoutes.ts ██████
|
||||
599 src/services/worker/OpenRouterAgent.ts █████
|
||||
574 src/services/worker/GeminiAgent.ts █████
|
||||
546 src/services/worker/SDKAgent.ts █████
|
||||
526 src/services/sqlite/SessionSearch.ts █████
|
||||
509 src/services/sqlite/migrations.ts █████
|
||||
466 src/services/worker/http/routes/DataRoutes.ts ████
|
||||
447 src/services/sqlite/PendingMessageStore.ts ████
|
||||
414 src/services/worker/http/routes/SettingsRoutes.ts ████
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Current | After Refactor |
|
||||
|--------|---------|----------------|
|
||||
| Files >500 lines | 14 | 0-2 |
|
||||
| Max file size | 2,034 | ~400 |
|
||||
| Code duplication | ~1,100 lines | ~100 lines |
|
||||
| Testable modules | Low | High |
|
||||
|
||||
**Recommended Start:** Phase 1 (SessionStore decomposition) - highest impact, clearest boundaries, and **growing** (now 2,011 lines with 49 methods).
|
||||
|
||||
### Key Observations Post-Merge
|
||||
|
||||
1. **SessionStore is still the top priority** - it grew by 108 lines and is now the 2nd largest file
|
||||
2. **SearchManager improved** - down 178 lines from error handling refactor
|
||||
3. **Agent files slightly smaller** - ~45 lines combined reduction
|
||||
4. **Core architecture unchanged** - the proposed modular structure remains valid
|
||||
@@ -1,106 +0,0 @@
|
||||
# Queue System Simplification Plan
|
||||
|
||||
## 1. Executive Summary
|
||||
The current queue system suffers from accidental complexity due to **state duplication** (in-memory vs. database), **fragile control flow** (recursive restarts), and **distributed state management**. This plan proposes a refactoring to establish the Database as the Single Source of Truth, unifying the processing logic into a robust, linear "Pump" model.
|
||||
|
||||
## 2. Identified Pain Points
|
||||
|
||||
1. **Dual State Synchronization:**
|
||||
* *Issue:* The system maintains both `session.pendingMessages` (in-memory array) and the `pending_messages` SQLite table.
|
||||
* *Impact:* Requires constant manual synchronization (push/shift/enqueue), leading to race conditions where the in-memory queue drifts from the DB state.
|
||||
|
||||
2. **Fragile Generator Lifecycle:**
|
||||
* *Issue:* The use of `startGeneratorWithProvider` and `startSessionWithAutoRestart` with recursive `setTimeout` calls to keep the processor alive is brittle.
|
||||
* *Impact:* Hard to debug, prone to stack issues or silent failures if the "chain" breaks.
|
||||
|
||||
3. **Non-Atomic State Transitions:**
|
||||
* *Issue:* The logic separates "peeking" a message from "marking it processing" (the "Critical Flow" identified in the analysis).
|
||||
* *Impact:* If the worker crashes or halts between these steps, messages can be processed twice or lost in limbo.
|
||||
|
||||
4. **Distributed Logic:**
|
||||
* *Issue:* Queue logic is scattered across `SessionManager` (coordination), `PendingMessageStore` (DB queries), `SDKAgent` (consumption), and `WorkerService` (orchestration).
|
||||
* *Impact:* Difficult to trace the lifecycle of a single message.
|
||||
|
||||
## 3. Proposed Architecture
|
||||
|
||||
### 3.1. Core Principle: "The Database is the Queue"
|
||||
We will eliminate the in-memory `pendingMessages` array entirely. The SQLite database will be the *only* place where queue state exists.
|
||||
|
||||
### 3.2. Architecture Components
|
||||
|
||||
#### A. Atomic `claimNextMessage()`
|
||||
Instead of `peek` then `mark`, we will implement a single atomic operation in `PendingMessageStore`.
|
||||
|
||||
* **Logic:**
|
||||
1. Find the oldest `pending` message for the session.
|
||||
2. Update it to `processing` and set the timestamp.
|
||||
3. Return the message record.
|
||||
* **SQL Strategy:** Use a transaction or `UPDATE ... RETURNING` (if supported) to ensure no other worker can claim the same message.
|
||||
|
||||
#### B. The `QueuePump` (Unified Processor)
|
||||
We will replace the recursive generator logic with a class (or function) dedicated to "pumping" messages for a specific session.
|
||||
|
||||
* **Pseudocode Structure:**
|
||||
```typescript
|
||||
async function runSessionPump(sessionId: number, signal: AbortSignal) {
|
||||
while (!signal.aborted) {
|
||||
// 1. Atomic Claim
|
||||
const message = store.claimNextMessage(sessionId);
|
||||
|
||||
if (!message) {
|
||||
// 2. Wait for signal (Event-driven, not polling)
|
||||
await waitForNewData(sessionId, signal);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. Process
|
||||
await sdkAgent.processMessage(message);
|
||||
|
||||
// 4. Mark Complete
|
||||
store.markProcessed(message.id);
|
||||
} catch (error) {
|
||||
// 5. Handle Failure
|
||||
store.markFailed(message.id, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3. Key Changes
|
||||
|
||||
| Component | Current State | Proposed State |
|
||||
| :--- | :--- | :--- |
|
||||
| **Storage** | In-memory Array + SQLite | SQLite Only |
|
||||
| **Consumption** | `yield` loop inside SDK Agent | `QueuePump` calls SDK Agent per message |
|
||||
| **Concurrency** | `peekPending` -> `markProcessing` (Race Prone) | `claimNextMessage` (Atomic Transaction) |
|
||||
| **Lifecycle** | Recursive `setTimeout` loops | Single `while` loop with `await` |
|
||||
| **Recovery** | `resetStuckMessages` (Global) | Pump handles own retries + Global cleanup on startup |
|
||||
|
||||
## 4. Implementation Steps
|
||||
|
||||
### Phase 1: Database Layer Hardening
|
||||
1. Add `claimNextMessage(sessionDbId)` to `PendingMessageStore`.
|
||||
* Must be transactional.
|
||||
* Returns `null` if no work is available.
|
||||
2. Ensure `markProcessed` and `markFailed` are robust.
|
||||
|
||||
### Phase 2: The Pump
|
||||
1. Create `SessionQueueProcessor.ts`.
|
||||
2. Implement the `while(!aborted)` loop.
|
||||
3. Integrate the `EventEmitter` to wake the loop when `enqueue()` happens (replacing the current polling-like behavior).
|
||||
|
||||
### Phase 3: SDK Integration
|
||||
1. Refactor `SDKAgent` to accept a *single* message or a streamlined iterator that doesn't manage queue state itself.
|
||||
2. Remove `session.pendingMessages` from `ActiveSession` type.
|
||||
|
||||
### Phase 4: Cleanup
|
||||
1. Remove `startGeneratorWithProvider` and `startSessionWithAutoRestart`.
|
||||
2. Remove `peekPending` (as it's replaced by `claimNextMessage`).
|
||||
3. Remove manual synchronization code in `SessionManager`.
|
||||
|
||||
## 5. Benefits
|
||||
* **Simplicity:** Code reduction of ~30-40%.
|
||||
* **Reliability:** Atomic database operations eliminate race conditions.
|
||||
* **Observability:** Linear control flow is easier to log and debug.
|
||||
* **Resilience:** Crashes are handled by simply restarting the Pump, which naturally picks up "processing" (stuck) or "pending" messages.
|
||||
@@ -1,46 +0,0 @@
|
||||
# Queue System Simplification Implementation
|
||||
|
||||
I have successfully implemented the queue system simplification plan.
|
||||
|
||||
## Changes Implemented
|
||||
|
||||
### 1. Database Layer Hardening
|
||||
- **Added `claimNextMessage(sessionDbId)` to `PendingMessageStore`:**
|
||||
- Implements an atomic transaction (SELECT oldest pending + UPDATE to processing).
|
||||
- Ensures a message can only be claimed by one worker at a time.
|
||||
- Eliminates race conditions between "peeking" and "marking".
|
||||
- **Removed `peekPending()`:**
|
||||
- No longer needed as `claimNextMessage` handles retrieval and locking in one step.
|
||||
|
||||
### 2. Unified "Pump" Architecture
|
||||
- **Created `src/services/queue/SessionQueueProcessor.ts`:**
|
||||
- Implements a robust `AsyncIterableIterator` that yields messages.
|
||||
- Encapsulates the "Claim -> Yield -> Wait" loop.
|
||||
- Replaces fragile polling/recursive logic with event-driven `waitForMessage`.
|
||||
- Handles empty queues gracefully by waiting for signals.
|
||||
|
||||
### 3. SessionManager Refactoring
|
||||
- **Updated `getMessageIterator`:**
|
||||
- Now delegates to `SessionQueueProcessor`.
|
||||
- Removes complex manual synchronization logic.
|
||||
- **Removed In-Memory Queue State:**
|
||||
- `queueObservation` and `queueSummarize` now only write to DB and emit events.
|
||||
- `pendingMessages` array is no longer used for logic (kept deprecated for type compatibility).
|
||||
- `getTotalActiveWork`, `hasPendingMessages`, etc., now query `PendingMessageStore` directly (counting both 'pending' and 'processing' states).
|
||||
|
||||
### 4. Logic Cleanup
|
||||
- **Removed Recursive Restarts:**
|
||||
- Refactored `startGeneratorWithProvider` in `SessionRoutes.ts` and `startSessionProcessor` in `WorkerService.ts`.
|
||||
- Removed logic that deleted sessions when queue emptied (sessions now wait for new work).
|
||||
- Removed "auto-restart" logic for normal completion (only kept for crash recovery).
|
||||
|
||||
## Benefits
|
||||
- **Reliability:** Atomic DB operations prevent stuck or duplicate messages.
|
||||
- **Simplicity:** Removed complex "peek-then-mark" and recursive restart chains.
|
||||
- **Performance:** Zero-latency event notification with efficient DB queries.
|
||||
- **Maintainability:** Clear separation of concerns (Store vs Processor vs Manager).
|
||||
|
||||
## Verification
|
||||
- Ran static analysis (`tsc`) to verify type safety of new components.
|
||||
- Verified removal of dead code (`peekPending`).
|
||||
- Confirmed integration points in `SessionManager` and `SessionRoutes`.
|
||||
@@ -1,742 +0,0 @@
|
||||
# Queue System Logic Report
|
||||
|
||||
This document provides a line-by-line analysis of the queue system in claude-mem, explaining **the reason behind each piece of logic** and **what it actually does**.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [High-Level Architecture](#high-level-architecture)
|
||||
2. [Message Status State Machine](#message-status-state-machine)
|
||||
3. [PendingMessageStore (Database Layer)](#pendingmessagestore-database-layer)
|
||||
4. [SessionManager (Queue Coordination)](#sessionmanager-queue-coordination)
|
||||
5. [SDKAgent (Message Consumer)](#sdkagent-message-consumer)
|
||||
6. [SessionRoutes (HTTP Entry Points)](#sessionroutes-http-entry-points)
|
||||
7. [WorkerService (Orchestrator)](#workerservice-orchestrator)
|
||||
8. [Critical Flow: How a Message Gets Stuck in "Processing"](#critical-flow-how-a-message-gets-stuck-in-processing)
|
||||
9. [Recovery Mechanisms](#recovery-mechanisms)
|
||||
|
||||
---
|
||||
|
||||
## High-Level Architecture
|
||||
|
||||
```
|
||||
Hook (post-tool-use/summary)
|
||||
│
|
||||
▼
|
||||
SessionRoutes.handleObservations/handleSummarize
|
||||
│
|
||||
▼
|
||||
SessionManager.queueObservation/queueSummarize
|
||||
│
|
||||
├─► PendingMessageStore.enqueue() [DB: status='pending']
|
||||
│
|
||||
├─► session.pendingMessages.push() [In-memory queue]
|
||||
│
|
||||
└─► emitter.emit('message') [Wake up generator]
|
||||
|
||||
│
|
||||
▼
|
||||
SDKAgent.createMessageGenerator (async generator)
|
||||
│
|
||||
├─► SessionManager.getMessageIterator()
|
||||
│ │
|
||||
│ ├─► PendingMessageStore.peekPending() [Find oldest pending]
|
||||
│ │
|
||||
│ ├─► PendingMessageStore.markProcessing() [DB: status='processing']
|
||||
│ │
|
||||
│ └─► yield message to SDK
|
||||
│
|
||||
▼
|
||||
SDK query() processes message and returns response
|
||||
│
|
||||
▼
|
||||
SDKAgent.processSDKResponse()
|
||||
│
|
||||
└─► SDKAgent.markMessagesProcessed()
|
||||
│
|
||||
└─► PendingMessageStore.markProcessed() [DB: status='processed']
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Message Status State Machine
|
||||
|
||||
```
|
||||
┌─────────────┐
|
||||
│ (new) │
|
||||
└──────┬──────┘
|
||||
│ enqueue()
|
||||
▼
|
||||
┌─────────────┐
|
||||
┌────│ pending │◄───────────────┐
|
||||
│ └──────┬──────┘ │
|
||||
│ │ markProcessing() │ markFailed() [retry_count < maxRetries]
|
||||
│ ▼ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ processing │────────────────┤
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ├─► markProcessed() │
|
||||
│ │ │ │
|
||||
│ │ ▼ │
|
||||
│ │ ┌─────────────┐ │
|
||||
│ │ │ processed │ │
|
||||
│ │ └─────────────┘ │
|
||||
│ │ │
|
||||
│ └─► markFailed() [retry_count >= maxRetries]
|
||||
│ │
|
||||
│ ▼
|
||||
│ ┌─────────────┐
|
||||
│ │ failed │
|
||||
│ └─────────────┘
|
||||
│
|
||||
│
|
||||
│ resetStuckMessages() [thresholdMs timeout]
|
||||
└───────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## PendingMessageStore (Database Layer)
|
||||
|
||||
### `enqueue()` (Lines 56-82)
|
||||
|
||||
```typescript
|
||||
enqueue(sessionDbId: number, claudeSessionId: string, message: PendingMessage): number {
|
||||
const now = Date.now();
|
||||
const stmt = this.db.prepare(`
|
||||
INSERT INTO pending_messages (
|
||||
session_db_id, claude_session_id, message_type,
|
||||
tool_name, tool_input, tool_response, cwd,
|
||||
last_user_message, last_assistant_message,
|
||||
prompt_number, status, retry_count, created_at_epoch
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', 0, ?)
|
||||
`);
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `const now = Date.now()` | Messages need timestamps for ordering and stuck-detection | Captures the moment the message was queued |
|
||||
| `status, retry_count ... 'pending', 0` | New messages start in pending state with no retries | Hard-codes initial state in SQL |
|
||||
| `created_at_epoch` | Need to track when message was originally queued for accurate observation timestamps | Used later when processing backlog to assign correct timestamps to observations |
|
||||
| `JSON.stringify(message.tool_input)` | SQLite can't store objects natively | Serializes complex tool data to string |
|
||||
| Returns `lastInsertRowid` | Caller needs the ID to track this specific message | Returns the database-assigned auto-increment ID |
|
||||
|
||||
### `peekPending()` (Lines 88-96)
|
||||
|
||||
```typescript
|
||||
peekPending(sessionDbId: number): PersistentPendingMessage | null {
|
||||
const stmt = this.db.prepare(`
|
||||
SELECT * FROM pending_messages
|
||||
WHERE session_db_id = ? AND status = 'pending'
|
||||
ORDER BY id ASC
|
||||
LIMIT 1
|
||||
`);
|
||||
return stmt.get(sessionDbId) as PersistentPendingMessage | null;
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `status = 'pending'` | Only look at messages not yet being processed | Filters out processing/processed/failed |
|
||||
| `ORDER BY id ASC` | Process messages in the order they arrived (FIFO) | Uses auto-increment ID as natural ordering |
|
||||
| `LIMIT 1` | Only need one message at a time for the iterator | Returns single oldest pending message |
|
||||
| Does NOT change status | Peek is non-destructive; status change happens separately in markProcessing | Allows checking without committing to process |
|
||||
|
||||
### `markProcessing()` (Lines 216-224)
|
||||
|
||||
```typescript
|
||||
markProcessing(messageId: number): void {
|
||||
const now = Date.now();
|
||||
const stmt = this.db.prepare(`
|
||||
UPDATE pending_messages
|
||||
SET status = 'processing', started_processing_at_epoch = ?
|
||||
WHERE id = ? AND status = 'pending'
|
||||
`);
|
||||
stmt.run(now, messageId);
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `status = 'processing'` | Mark this message as "in progress" so other consumers don't pick it up | Prevents duplicate processing |
|
||||
| `started_processing_at_epoch = ?` | Track when processing started for stuck detection | If processing takes >5min, considered stuck |
|
||||
| `WHERE ... AND status = 'pending'` | Only transition from pending->processing (idempotent safety) | Prevents double-processing race conditions |
|
||||
|
||||
### `markProcessed()` (Lines 230-242)
|
||||
|
||||
```typescript
|
||||
markProcessed(messageId: number): void {
|
||||
const now = Date.now();
|
||||
const stmt = this.db.prepare(`
|
||||
UPDATE pending_messages
|
||||
SET
|
||||
status = 'processed',
|
||||
completed_at_epoch = ?,
|
||||
tool_input = NULL,
|
||||
tool_response = NULL
|
||||
WHERE id = ? AND status = 'processing'
|
||||
`);
|
||||
stmt.run(now, messageId);
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `status = 'processed'` | Message successfully handled, move to terminal state | Marks completion |
|
||||
| `completed_at_epoch = ?` | Track when processing finished for metrics/display | Records completion time |
|
||||
| `tool_input = NULL, tool_response = NULL` | Large payload data no longer needed after successful processing | Frees space - observations are already saved elsewhere |
|
||||
| `WHERE ... AND status = 'processing'` | Only transition from processing->processed | Ensures we only complete messages we actually processed |
|
||||
|
||||
### `markFailed()` (Lines 249-274)
|
||||
|
||||
```typescript
|
||||
markFailed(messageId: number): void {
|
||||
const msg = this.db.prepare('SELECT retry_count FROM pending_messages WHERE id = ?').get(messageId);
|
||||
|
||||
if (msg.retry_count < this.maxRetries) {
|
||||
// Move back to pending for retry
|
||||
const stmt = this.db.prepare(`
|
||||
UPDATE pending_messages
|
||||
SET status = 'pending', retry_count = retry_count + 1, started_processing_at_epoch = NULL
|
||||
WHERE id = ?
|
||||
`);
|
||||
} else {
|
||||
// Max retries exceeded, mark as permanently failed
|
||||
const stmt = this.db.prepare(`
|
||||
UPDATE pending_messages
|
||||
SET status = 'failed', completed_at_epoch = ?
|
||||
WHERE id = ?
|
||||
`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Check `retry_count < maxRetries` | Don't retry forever - eventually give up | Implements bounded retry policy (default: 3) |
|
||||
| `status = 'pending'` (retry path) | Put message back in queue for another attempt | Allows automatic recovery |
|
||||
| `retry_count + 1` | Track how many times we've tried | Increment toward failure threshold |
|
||||
| `started_processing_at_epoch = NULL` | Clear the processing timestamp for next attempt | Prevents stuck detection from immediately triggering |
|
||||
| `status = 'failed'` (terminal) | Message is permanently broken, stop trying | Prevents infinite retry loops |
|
||||
|
||||
### `resetStuckMessages()` (Lines 281-292)
|
||||
|
||||
```typescript
|
||||
resetStuckMessages(thresholdMs: number): number {
|
||||
const cutoff = thresholdMs === 0 ? Date.now() : Date.now() - thresholdMs;
|
||||
|
||||
const stmt = this.db.prepare(`
|
||||
UPDATE pending_messages
|
||||
SET status = 'pending', started_processing_at_epoch = NULL
|
||||
WHERE status = 'processing' AND started_processing_at_epoch < ?
|
||||
`);
|
||||
|
||||
return result.changes;
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `thresholdMs === 0 ? Date.now()` | Special case: threshold=0 means "reset all processing messages" | Allows forced recovery of all stuck messages |
|
||||
| `Date.now() - thresholdMs` | Calculate cutoff time (e.g., 5 minutes ago) | Messages processing longer than this are stuck |
|
||||
| `status = 'processing'` condition | Only reset messages actively being processed | Don't touch pending or completed messages |
|
||||
| `started_processing_at_epoch < ?` | Processing started before cutoff = stuck | Time-based stuck detection |
|
||||
| `SET status = 'pending'` | Move back to queue for retry | Enables automatic recovery |
|
||||
| Returns `result.changes` | Caller needs to know how many were recovered | For logging/metrics |
|
||||
|
||||
### `getPendingCount()` (Lines 297-304)
|
||||
|
||||
```typescript
|
||||
getPendingCount(sessionDbId: number): number {
|
||||
const stmt = this.db.prepare(`
|
||||
SELECT COUNT(*) as count FROM pending_messages
|
||||
WHERE session_db_id = ? AND status IN ('pending', 'processing')
|
||||
`);
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `status IN ('pending', 'processing')` | **CRITICAL**: Counts BOTH pending AND processing | Used to decide if generator should keep running |
|
||||
| Why include processing? | A message in processing state is still "work to be done" | Prevents generator from stopping while SDK is mid-response |
|
||||
|
||||
---
|
||||
|
||||
## SessionManager (Queue Coordination)
|
||||
|
||||
### `queueObservation()` (Lines 181-232)
|
||||
|
||||
```typescript
|
||||
queueObservation(sessionDbId: number, data: ObservationData): void {
|
||||
// Auto-initialize from database if needed
|
||||
let session = this.sessions.get(sessionDbId);
|
||||
if (!session) {
|
||||
session = this.initializeSession(sessionDbId);
|
||||
}
|
||||
|
||||
// CRITICAL: Persist to database FIRST
|
||||
const message: PendingMessage = { type: 'observation', ... };
|
||||
const messageId = this.getPendingStore().enqueue(sessionDbId, session.claudeSessionId, message);
|
||||
|
||||
// Add to in-memory queue
|
||||
session.pendingMessages.push(message);
|
||||
|
||||
// Notify generator immediately
|
||||
const emitter = this.sessionQueues.get(sessionDbId);
|
||||
emitter?.emit('message');
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Auto-initialize session | Worker may have restarted, need to rebuild in-memory state | Lazy initialization from database |
|
||||
| `enqueue()` BEFORE in-memory push | **CRITICAL**: Database is source of truth, survives crashes | Persist-first ensures no data loss |
|
||||
| `session.pendingMessages.push()` | In-memory queue for backward compatibility and fast status checks | Mirrors database state in RAM |
|
||||
| `emitter?.emit('message')` | Wake up the generator immediately (zero-latency) | Event-driven, no polling needed |
|
||||
|
||||
### `getMessageIterator()` (Lines 397-477)
|
||||
|
||||
```typescript
|
||||
async *getMessageIterator(sessionDbId: number): AsyncIterableIterator<PendingMessageWithId> {
|
||||
while (!session.abortController.signal.aborted) {
|
||||
// Check for pending messages in persistent store
|
||||
const persistentMessage = this.getPendingStore().peekPending(sessionDbId);
|
||||
|
||||
if (!persistentMessage) {
|
||||
// Wait for new message event
|
||||
await new Promise<void>(resolve => {
|
||||
emitter.once('message', messageHandler);
|
||||
session.abortController.signal.addEventListener('abort', abortHandler, { once: true });
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Mark as processing BEFORE yielding
|
||||
this.getPendingStore().markProcessing(persistentMessage.id);
|
||||
|
||||
// Track this message ID for completion marking
|
||||
session.pendingProcessingIds.add(persistentMessage.id);
|
||||
|
||||
// Convert and yield
|
||||
const message: PendingMessageWithId = {
|
||||
_persistentId: persistentMessage.id,
|
||||
_originalTimestamp: persistentMessage.created_at_epoch,
|
||||
...this.getPendingStore().toPendingMessage(persistentMessage)
|
||||
};
|
||||
|
||||
yield message;
|
||||
|
||||
// Remove from in-memory queue after yielding
|
||||
session.pendingMessages.shift();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `while (!aborted)` | Keep processing until session ends | Continuous processing loop |
|
||||
| `peekPending()` | Check database for work | Non-destructively looks for pending messages |
|
||||
| `await new Promise` with event | Block until message arrives (no polling) | Event-driven wake-up saves CPU |
|
||||
| `markProcessing()` BEFORE yield | **CRITICAL**: Claim the message before giving to SDK | Prevents race conditions |
|
||||
| `pendingProcessingIds.add()` | Track which messages are being processed | So we know what to mark as completed |
|
||||
| `_persistentId` field | Attach database ID to in-flight message | Needed for markProcessed() later |
|
||||
| `_originalTimestamp` | Preserve original queue time | For accurate observation timestamps when processing backlog |
|
||||
| `pendingMessages.shift()` after yield | Keep in-memory queue in sync with database | Mirrors the database state change |
|
||||
|
||||
---
|
||||
|
||||
## SDKAgent (Message Consumer)
|
||||
|
||||
### `startSession()` Main Loop (Lines 75-150)
|
||||
|
||||
```typescript
|
||||
const queryResult = query({
|
||||
prompt: messageGenerator,
|
||||
options: {
|
||||
model: modelId,
|
||||
resume: session.claudeSessionId, // <-- Session continuity
|
||||
disallowedTools,
|
||||
abortController: session.abortController,
|
||||
pathToClaudeCodeExecutable: claudePath
|
||||
}
|
||||
});
|
||||
|
||||
for await (const message of queryResult) {
|
||||
if (message.type === 'assistant') {
|
||||
// Process response
|
||||
await this.processSDKResponse(session, textContent, worker, discoveryTokens, originalTimestamp);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `resume: session.claudeSessionId` | **CRITICAL**: Connect to existing Claude session | Enables session continuity - same transcript across prompts |
|
||||
| `for await` loop | Process SDK responses as they arrive | Streaming response handling |
|
||||
| `processSDKResponse()` called per response | Parse and save observations/summaries | Database + Chroma sync |
|
||||
|
||||
### `createMessageGenerator()` (Lines 202-291)
|
||||
|
||||
```typescript
|
||||
private async *createMessageGenerator(session: ActiveSession): AsyncIterableIterator<SDKUserMessage> {
|
||||
// Build initial or continuation prompt
|
||||
const initPrompt = isInitPrompt
|
||||
? buildInitPrompt(...)
|
||||
: buildContinuationPrompt(...);
|
||||
|
||||
// Yield initial prompt
|
||||
yield { type: 'user', message: { role: 'user', content: initPrompt }, session_id: session.claudeSessionId };
|
||||
|
||||
// Consume pending messages
|
||||
for await (const message of this.sessionManager.getMessageIterator(session.sessionDbId)) {
|
||||
if (message.type === 'observation') {
|
||||
const obsPrompt = buildObservationPrompt({ ... });
|
||||
yield { type: 'user', message: { role: 'user', content: obsPrompt } };
|
||||
} else if (message.type === 'summarize') {
|
||||
const summaryPrompt = buildSummaryPrompt({ ... });
|
||||
yield { type: 'user', message: { role: 'user', content: summaryPrompt } };
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `isInitPrompt` check | First prompt needs full context, subsequent prompts need continuation | Different prompt templates |
|
||||
| `yield` initial prompt | Start the SDK conversation | Sends initialization to Claude |
|
||||
| `for await ... getMessageIterator` | Pull messages as they become available | Event-driven message consumption |
|
||||
| `yield` for each message | Feed observations/summaries to SDK one at a time | SDK processes each and responds |
|
||||
|
||||
### `markMessagesProcessed()` (Lines 462-491)
|
||||
|
||||
```typescript
|
||||
private async markMessagesProcessed(session: ActiveSession, worker: any): Promise<void> {
|
||||
const pendingMessageStore = this.sessionManager.getPendingMessageStore();
|
||||
|
||||
if (session.pendingProcessingIds.size > 0) {
|
||||
for (const messageId of session.pendingProcessingIds) {
|
||||
pendingMessageStore.markProcessed(messageId);
|
||||
}
|
||||
session.pendingProcessingIds.clear();
|
||||
session.earliestPendingTimestamp = null;
|
||||
|
||||
// Cleanup old processed messages
|
||||
const deletedCount = pendingMessageStore.cleanupProcessed(100);
|
||||
}
|
||||
|
||||
// Broadcast status update
|
||||
if (worker && typeof worker.broadcastProcessingStatus === 'function') {
|
||||
worker.broadcastProcessingStatus();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Loop over `pendingProcessingIds` | Mark ALL messages that were yielded to SDK | Batch completion |
|
||||
| `markProcessed()` for each | Transition processing->processed in database | Completes the message lifecycle |
|
||||
| `.clear()` | Reset tracking set for next batch | Prepare for next iteration |
|
||||
| `earliestPendingTimestamp = null` | Reset timestamp tracking | Next batch gets fresh timestamps |
|
||||
| `cleanupProcessed(100)` | Don't keep infinite processed messages | Retention policy |
|
||||
| `broadcastProcessingStatus()` | Update UI with new state | SSE broadcast |
|
||||
|
||||
---
|
||||
|
||||
## SessionRoutes (HTTP Entry Points)
|
||||
|
||||
### `startGeneratorWithProvider()` (Lines 118-189)
|
||||
|
||||
```typescript
|
||||
private startGeneratorWithProvider(session, provider, source): void {
|
||||
session.currentProvider = provider;
|
||||
|
||||
session.generatorPromise = agent.startSession(session, this.workerService)
|
||||
.catch(error => {
|
||||
// Mark all processing messages as failed
|
||||
const processingMessages = stmt.all(session.sessionDbId);
|
||||
for (const msg of processingMessages) {
|
||||
pendingStore.markFailed(msg.id);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
session.generatorPromise = null;
|
||||
session.currentProvider = null;
|
||||
this.workerService.broadcastProcessingStatus();
|
||||
|
||||
// Check if there's more work pending
|
||||
const pendingCount = pendingStore.getPendingCount(sessionDbId);
|
||||
if (pendingCount > 0) {
|
||||
// Auto-restart
|
||||
setTimeout(() => {
|
||||
if (stillExists && !stillExists.generatorPromise) {
|
||||
this.startGeneratorWithProvider(stillExists, this.getSelectedProvider(), 'auto-restart');
|
||||
}
|
||||
}, 0);
|
||||
} else {
|
||||
// Cleanup
|
||||
this.sessionManager.deleteSession(sessionDbId);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| `session.generatorPromise =` | Track that generator is running | Prevents multiple generators per session |
|
||||
| `.catch()` with markFailed | If generator crashes, don't lose messages | Marks for retry or permanent failure |
|
||||
| `.finally()` | Always cleanup regardless of success/failure | Guaranteed cleanup |
|
||||
| `generatorPromise = null` | Allow new generator to start | Clears the "running" flag |
|
||||
| `getPendingCount() > 0` | **CRITICAL**: Check if more work arrived while processing | Handles messages queued during SDK call |
|
||||
| `setTimeout(..., 0)` | Don't restart synchronously (could cause stack issues) | Deferred restart |
|
||||
| `deleteSession()` when no work | Clean up resources | Memory management |
|
||||
|
||||
### `ensureGeneratorRunning()` (Lines 90-113)
|
||||
|
||||
```typescript
|
||||
private ensureGeneratorRunning(sessionDbId: number, source: string): void {
|
||||
const session = this.sessionManager.getSession(sessionDbId);
|
||||
if (!session) return;
|
||||
|
||||
const selectedProvider = this.getSelectedProvider();
|
||||
|
||||
// Start generator if not running
|
||||
if (!session.generatorPromise) {
|
||||
this.startGeneratorWithProvider(session, selectedProvider, source);
|
||||
return;
|
||||
}
|
||||
|
||||
// Generator is running - check if provider changed
|
||||
if (session.currentProvider && session.currentProvider !== selectedProvider) {
|
||||
// Let current generator finish, next one will use new provider
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Check `!generatorPromise` | Only start if not already running | Prevents duplicate generators |
|
||||
| Start generator if not running | Ensure messages get processed | Lazy generator startup |
|
||||
| Provider change detection | Allow switching providers mid-session | Graceful provider transition |
|
||||
|
||||
---
|
||||
|
||||
## WorkerService (Orchestrator)
|
||||
|
||||
### `initializeBackground()` Stuck Message Recovery (Lines 627-633)
|
||||
|
||||
```typescript
|
||||
// Recover stuck messages from previous crashes
|
||||
const STUCK_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes
|
||||
const resetCount = pendingStore.resetStuckMessages(STUCK_THRESHOLD_MS);
|
||||
if (resetCount > 0) {
|
||||
logger.info('SYSTEM', `Recovered ${resetCount} stuck messages from previous session`);
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Called at startup | Worker may have crashed while messages were processing | Recovery mechanism |
|
||||
| 5 minute threshold | If processing >5min, something went wrong | Reasonable timeout for SDK calls |
|
||||
| Reset to pending | Give stuck messages another chance | Automatic retry |
|
||||
|
||||
### `processPendingQueues()` (Lines 747-811)
|
||||
|
||||
```typescript
|
||||
async processPendingQueues(sessionLimit: number = 10): Promise<Result> {
|
||||
const orphanedSessionIds = pendingStore.getSessionsWithPendingMessages();
|
||||
|
||||
for (const sessionDbId of orphanedSessionIds) {
|
||||
// Skip if session already has active generator
|
||||
const existingSession = this.sessionManager.getSession(sessionDbId);
|
||||
if (existingSession?.generatorPromise) {
|
||||
result.sessionsSkipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialize session and start SDK agent
|
||||
const session = this.sessionManager.initializeSession(sessionDbId);
|
||||
this.startSessionWithAutoRestart(session, getPendingCount, 'startup-recovery');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Called at startup | Resume work interrupted by crash/restart | Auto-recovery |
|
||||
| `getSessionsWithPendingMessages()` | Find sessions that have orphaned work | Database query |
|
||||
| Skip if generator running | Don't start duplicate processors | Race condition prevention |
|
||||
| `startSessionWithAutoRestart()` | Start processing with auto-restart logic | Shares code with SessionRoutes |
|
||||
|
||||
### `startSessionWithAutoRestart()` (Lines 696-739)
|
||||
|
||||
```typescript
|
||||
private startSessionWithAutoRestart(session, getPendingCount, source): void {
|
||||
session.generatorPromise = this.sdkAgent.startSession(session, this)
|
||||
.catch(error => { ... })
|
||||
.finally(() => {
|
||||
session.generatorPromise = null;
|
||||
this.broadcastProcessingStatus();
|
||||
|
||||
const stillPending = getPendingCount(sid);
|
||||
if (stillPending > 0) {
|
||||
// Recursive restart
|
||||
setTimeout(() => {
|
||||
const stillExists = this.sessionManager.getSession(sid);
|
||||
if (stillExists && !stillExists.generatorPromise) {
|
||||
this.startSessionWithAutoRestart(stillExists, getPendingCount, 'auto-restart');
|
||||
}
|
||||
}, 0);
|
||||
} else {
|
||||
// Cleanup
|
||||
this.sessionManager.deleteSession(sid);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
| Line | The Reason Behind This | What It Actually Does |
|
||||
|------|------------------------|----------------------|
|
||||
| Same pattern as SessionRoutes | **DRY**: Shared auto-restart logic | Prevents code duplication |
|
||||
| Recursive restart | Keep processing until queue is empty | Ensures all messages processed |
|
||||
| Check `stillExists` before restart | Session might have been deleted | Safety check |
|
||||
|
||||
---
|
||||
|
||||
## Critical Flow: How a Message Gets Stuck in "Processing"
|
||||
|
||||
### The Problem
|
||||
|
||||
Messages can get stuck in `status = 'processing'` if:
|
||||
|
||||
1. **SDK call hangs indefinitely** - The Agent SDK query never returns
|
||||
2. **Worker crashes mid-processing** - Process dies before markProcessed()
|
||||
3. **Exception in processSDKResponse()** - Error prevents markProcessed() from running
|
||||
|
||||
### The Flow
|
||||
|
||||
```
|
||||
1. queueObservation() called
|
||||
└─► enqueue() → status = 'pending'
|
||||
|
||||
2. getMessageIterator() picks up message
|
||||
└─► markProcessing() → status = 'processing' ✓
|
||||
└─► pendingProcessingIds.add(id)
|
||||
└─► yield message to SDK
|
||||
|
||||
3. SDK processes and returns response
|
||||
└─► processSDKResponse() called
|
||||
└─► Parse observations/summaries
|
||||
└─► Store to database
|
||||
└─► markMessagesProcessed()
|
||||
└─► markProcessed() → status = 'processed' ✓
|
||||
|
||||
IF STEP 3 FAILS OR HANGS:
|
||||
└─► Message stays in 'processing' forever
|
||||
└─► Recovery: resetStuckMessages() after 5 minutes
|
||||
```
|
||||
|
||||
### Why Processing Messages Can Get "Lost"
|
||||
|
||||
**Race Condition in getMessageIterator():**
|
||||
|
||||
```typescript
|
||||
// Lines 445-446 in SessionManager
|
||||
this.getPendingStore().markProcessing(persistentMessage.id);
|
||||
session.pendingProcessingIds.add(persistentMessage.id);
|
||||
```
|
||||
|
||||
The message is marked as `processing` BEFORE being yielded. If the SDK hangs or crashes AFTER this line but BEFORE processSDKResponse completes, the message is stuck.
|
||||
|
||||
**Protection Mechanisms:**
|
||||
|
||||
1. `pendingProcessingIds` tracks what's in-flight
|
||||
2. `markFailed()` in catch handler marks for retry
|
||||
3. `resetStuckMessages()` at startup cleans up old stuck messages
|
||||
|
||||
---
|
||||
|
||||
## Recovery Mechanisms
|
||||
|
||||
### 1. Startup Recovery (Worker crashes)
|
||||
|
||||
```typescript
|
||||
// In initializeBackground()
|
||||
const resetCount = pendingStore.resetStuckMessages(STUCK_THRESHOLD_MS);
|
||||
```
|
||||
|
||||
- Runs when worker starts
|
||||
- Finds messages stuck in `processing` for >5 minutes
|
||||
- Resets them to `pending` for retry
|
||||
|
||||
### 2. Generator Error Recovery
|
||||
|
||||
```typescript
|
||||
// In startGeneratorWithProvider() catch handler
|
||||
for (const msg of processingMessages) {
|
||||
pendingStore.markFailed(msg.id);
|
||||
}
|
||||
```
|
||||
|
||||
- Runs when SDK call throws
|
||||
- Marks processing messages as failed (which may reset to pending if retries remain)
|
||||
|
||||
### 3. Auto-Restart Recovery
|
||||
|
||||
```typescript
|
||||
// In startGeneratorWithProvider() finally handler
|
||||
if (pendingCount > 0) {
|
||||
setTimeout(() => startGeneratorWithProvider(...), 0);
|
||||
}
|
||||
```
|
||||
|
||||
- Runs after every generator completes
|
||||
- Checks for pending work
|
||||
- Starts new generator if work remains
|
||||
|
||||
### 4. Manual Recovery (UI)
|
||||
|
||||
```typescript
|
||||
// PendingMessageStore methods
|
||||
retryMessage(messageId) // Reset specific message to pending
|
||||
retryAllStuck(thresholdMs) // Reset all stuck messages
|
||||
abortMessage(messageId) // Delete message from queue
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary of Potential Issues
|
||||
|
||||
| Issue | Cause | Mitigation |
|
||||
|-------|-------|------------|
|
||||
| Message stuck in processing | SDK hang, crash during processing | `resetStuckMessages()` at startup |
|
||||
| Duplicate processing | Race condition on message claim | `markProcessing()` with `WHERE status = 'pending'` |
|
||||
| Lost messages | Crash before enqueue | DB persist BEFORE in-memory push |
|
||||
| Generator never starts | No call to `ensureGeneratorRunning()` | Called by every HTTP handler |
|
||||
| Generator exits early | Empty queue check race | `finally` handler checks and restarts |
|
||||
| Infinite retry | Repeated failures | `maxRetries` limit (default: 3) |
|
||||
|
||||
---
|
||||
|
||||
## Diagnostic Queries
|
||||
|
||||
Check for stuck messages:
|
||||
```sql
|
||||
SELECT * FROM pending_messages
|
||||
WHERE status = 'processing'
|
||||
AND started_processing_at_epoch < (strftime('%s', 'now') * 1000 - 300000);
|
||||
```
|
||||
|
||||
Check queue depth by session:
|
||||
```sql
|
||||
SELECT session_db_id, status, COUNT(*)
|
||||
FROM pending_messages
|
||||
GROUP BY session_db_id, status;
|
||||
```
|
||||
|
||||
Check retry counts:
|
||||
```sql
|
||||
SELECT id, message_type, retry_count, status
|
||||
FROM pending_messages
|
||||
WHERE retry_count > 0;
|
||||
```
|
||||
@@ -1,4 +1,12 @@
|
||||
<p align="center">
|
||||
Official $CMEM Links:
|
||||
<a href="https://bags.fm/2TsmuYUrsctE57VLckZBYEEzdokUF8j8e1GavekWBAGS">Bags.fm</a> •
|
||||
<a href="https://jup.ag/tokens/2TsmuYUrsctE57VLckZBYEEzdokUF8j8e1GavekWBAGS">Jupiter</a> •
|
||||
<a href="https://photon-sol.tinyastro.io/en/lp/6MzFAkWnac6GSK1EdFX93dZeukGfzrFq4UHWarhGSQyd">Photon</a> •
|
||||
<a href="https://dexscreener.com/solana/6mzfakwnac6gsk1edfx93dzeukgfzrfq4uhwarhgsqyd">DEXScreener</a>
|
||||
</p>
|
||||
|
||||
<p align="center">Official CA: 2TsmuYUrsctE57VLckZBYEEzdokUF8j8e1GavekWBAGS (on Solana)</p>
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
@@ -14,12 +22,14 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="docs/i18n/README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="docs/i18n/README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="docs/i18n/README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="docs/i18n/README.pt.md">🇵🇹 Português</a> •
|
||||
<a href="docs/i18n/README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="docs/i18n/README.ko.md">🇰🇷 한국어</a> •
|
||||
<a href="docs/i18n/README.es.md">🇪🇸 Español</a> •
|
||||
<a href="docs/i18n/README.de.md">🇩🇪 Deutsch</a> •
|
||||
<a href="docs/i18n/README.fr.md">🇫🇷 Français</a>
|
||||
<a href="docs/i18n/README.fr.md">🇫🇷 Français</a> •
|
||||
<a href="docs/i18n/README.he.md">🇮🇱 עברית</a> •
|
||||
<a href="docs/i18n/README.ar.md">🇸🇦 العربية</a> •
|
||||
<a href="docs/i18n/README.ru.md">🇷🇺 Русский</a> •
|
||||
@@ -29,10 +39,12 @@
|
||||
<a href="docs/i18n/README.tr.md">🇹🇷 Türkçe</a> •
|
||||
<a href="docs/i18n/README.uk.md">🇺🇦 Українська</a> •
|
||||
<a href="docs/i18n/README.vi.md">🇻🇳 Tiếng Việt</a> •
|
||||
<a href="docs/i18n/README.tl.md">🇵🇭 Tagalog</a> •
|
||||
<a href="docs/i18n/README.id.md">🇮🇩 Indonesia</a> •
|
||||
<a href="docs/i18n/README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="docs/i18n/README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="docs/i18n/README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="docs/i18n/README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="docs/i18n/README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="docs/i18n/README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="docs/i18n/README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -101,13 +113,25 @@
|
||||
Start a new Claude Code session in the terminal and enter the following commands:
|
||||
|
||||
```
|
||||
> /plugin marketplace add thedotmack/claude-mem
|
||||
/plugin marketplace add thedotmack/claude-mem
|
||||
|
||||
> /plugin install claude-mem
|
||||
/plugin install claude-mem
|
||||
```
|
||||
|
||||
Restart Claude Code. Context from previous sessions will automatically appear in new sessions.
|
||||
|
||||
> **Note:** Claude-Mem is also published on npm, but `npm install -g claude-mem` installs the **SDK/library only** — it does not register the plugin hooks or set up the worker service. To use Claude-Mem as a plugin, always install via the `/plugin` commands above.
|
||||
|
||||
### 🦞 OpenClaw Gateway
|
||||
|
||||
Install claude-mem as a persistent memory plugin on [OpenClaw](https://openclaw.ai) gateways with a single command:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://install.cmem.ai/openclaw.sh | bash
|
||||
```
|
||||
|
||||
The installer handles dependencies, plugin setup, AI provider configuration, worker startup, and optional real-time observation feeds to Telegram, Discord, Slack, and more. See the [OpenClaw Integration Guide](https://docs.claude-mem.ai/openclaw-integration) for details.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- 🧠 **Persistent Memory** - Context survives across sessions
|
||||
@@ -125,7 +149,7 @@ Restart Claude Code. Context from previous sessions will automatically appear in
|
||||
|
||||
## Documentation
|
||||
|
||||
📚 **[View Full Documentation](docs/)** - Browse markdown docs on GitHub
|
||||
📚 **[View Full Documentation](https://docs.claude-mem.ai/)** - Browse on official website
|
||||
|
||||
### Getting Started
|
||||
|
||||
@@ -174,7 +198,7 @@ See [Architecture Overview](https://docs.claude-mem.ai/architecture/overview) fo
|
||||
|
||||
## MCP Search Tools
|
||||
|
||||
Claude-Mem provides intelligent memory search through **4 MCP tools** following a token-efficient **3-layer workflow pattern**:
|
||||
Claude-Mem provides intelligent memory search through **5 MCP tools** following a token-efficient **3-layer workflow pattern**:
|
||||
|
||||
**The 3-Layer Workflow:**
|
||||
|
||||
@@ -187,6 +211,7 @@ Claude-Mem provides intelligent memory search through **4 MCP tools** following
|
||||
- Start with `search` to get an index of results
|
||||
- Use `timeline` to see what was happening around specific observations
|
||||
- Use `get_observations` to fetch full details for relevant IDs
|
||||
- Use `save_memory` to manually store important information
|
||||
- **~10x token savings** by filtering before fetching details
|
||||
|
||||
**Available MCP Tools:**
|
||||
@@ -194,7 +219,8 @@ Claude-Mem provides intelligent memory search through **4 MCP tools** following
|
||||
1. **`search`** - Search memory index with full-text queries, filters by type/date/project
|
||||
2. **`timeline`** - Get chronological context around a specific observation or query
|
||||
3. **`get_observations`** - Fetch full observation details by IDs (always batch multiple IDs)
|
||||
4. **`__IMPORTANT`** - Workflow documentation (always visible to Claude)
|
||||
4. **`save_memory`** - Manually save a memory/observation for semantic search
|
||||
5. **`__IMPORTANT`** - Workflow documentation (always visible to Claude)
|
||||
|
||||
**Example Usage:**
|
||||
|
||||
@@ -206,6 +232,9 @@ search(query="authentication bug", type="bugfix", limit=10)
|
||||
|
||||
// Step 3: Fetch full details
|
||||
get_observations(ids=[123, 456])
|
||||
|
||||
// Save important information manually
|
||||
save_memory(text="API requires auth header X-API-Key", title="API Auth")
|
||||
```
|
||||
|
||||
See [Search Tools Guide](https://docs.claude-mem.ai/usage/search-tools) for detailed examples.
|
||||
@@ -228,6 +257,17 @@ See **[Beta Features Documentation](https://docs.claude-mem.ai/beta-features)**
|
||||
- **uv**: Python package manager for vector search (auto-installed if missing)
|
||||
- **SQLite 3**: For persistent storage (bundled)
|
||||
|
||||
---
|
||||
### Windows Setup Notes
|
||||
|
||||
If you see an error like:
|
||||
|
||||
```powershell
|
||||
npm : The term 'npm' is not recognized as the name of a cmdlet
|
||||
```
|
||||
|
||||
Make sure Node.js and npm are installed and added to your PATH. Download the latest Node.js installer from https://nodejs.org and restart your terminal after installation.
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
@@ -299,6 +339,8 @@ See the [LICENSE](LICENSE) file for full details.
|
||||
- **Documentation**: [docs/](docs/)
|
||||
- **Issues**: [GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
|
||||
- **Repository**: [github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
|
||||
- **Official X Account**: [@Claude_Memory](https://x.com/Claude_Memory)
|
||||
- **Official Discord**: [Join Discord](https://discord.com/invite/J4wttp9vDu)
|
||||
- **Author**: Alex Newman ([@thedotmack](https://github.com/thedotmack))
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"scripts": {
|
||||
"setup": "cp ../settings.local.json .claude/settings.local.json && npm install",
|
||||
"run": "npm run build-and-sync"
|
||||
}
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
# Common utility functions for Cursor hooks (PowerShell)
|
||||
# Dot-source this file in hook scripts: . "$PSScriptRoot\common.ps1"
|
||||
# Note: ErrorActionPreference should be set in each script, not globally here
|
||||
|
||||
# Get worker port from settings with validation
|
||||
function Get-WorkerPort {
|
||||
$settingsPath = Join-Path $env:USERPROFILE ".claude-mem\settings.json"
|
||||
$port = 37777
|
||||
|
||||
if (Test-Path $settingsPath) {
|
||||
try {
|
||||
$settings = Get-Content $settingsPath -Raw | ConvertFrom-Json
|
||||
if ($settings.CLAUDE_MEM_WORKER_PORT) {
|
||||
$parsedPort = [int]$settings.CLAUDE_MEM_WORKER_PORT
|
||||
if ($parsedPort -ge 1 -and $parsedPort -le 65535) {
|
||||
$port = $parsedPort
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
# Ignore parse errors, use default
|
||||
}
|
||||
}
|
||||
|
||||
return $port
|
||||
}
|
||||
|
||||
# Ensure worker is running with retries
|
||||
function Test-WorkerReady {
|
||||
param(
|
||||
[int]$Port = 37777,
|
||||
[int]$MaxRetries = 75
|
||||
)
|
||||
|
||||
for ($i = 0; $i -lt $MaxRetries; $i++) {
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "http://127.0.0.1:$Port/api/readiness" -Method Get -TimeoutSec 1 -ErrorAction Stop
|
||||
return $true
|
||||
} catch {
|
||||
Start-Sleep -Milliseconds 200
|
||||
}
|
||||
}
|
||||
|
||||
return $false
|
||||
}
|
||||
|
||||
# Get project name from workspace root
|
||||
function Get-ProjectName {
|
||||
param([string]$WorkspaceRoot)
|
||||
|
||||
if ([string]::IsNullOrEmpty($WorkspaceRoot)) {
|
||||
return "unknown-project"
|
||||
}
|
||||
|
||||
# Handle Windows drive root (e.g., "C:\")
|
||||
if ($WorkspaceRoot -match '^([A-Za-z]):\\?$') {
|
||||
return "drive-$($Matches[1].ToUpper())"
|
||||
}
|
||||
|
||||
$projectName = Split-Path $WorkspaceRoot -Leaf
|
||||
if ([string]::IsNullOrEmpty($projectName)) {
|
||||
return "unknown-project"
|
||||
}
|
||||
|
||||
return $projectName
|
||||
}
|
||||
|
||||
# URL encode a string
|
||||
function Get-UrlEncodedString {
|
||||
param([string]$String)
|
||||
|
||||
if ([string]::IsNullOrEmpty($String)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
return [System.Uri]::EscapeDataString($String)
|
||||
}
|
||||
|
||||
# Check if string is empty or null
|
||||
function Test-IsEmpty {
|
||||
param([string]$String)
|
||||
|
||||
return [string]::IsNullOrEmpty($String) -or $String -eq "null" -or $String -eq "empty"
|
||||
}
|
||||
|
||||
# Safely read JSON from stdin with error handling
|
||||
function Read-JsonInput {
|
||||
try {
|
||||
$input = [Console]::In.ReadToEnd()
|
||||
if ([string]::IsNullOrEmpty($input)) {
|
||||
return @{}
|
||||
}
|
||||
return $input | ConvertFrom-Json -ErrorAction Stop
|
||||
} catch {
|
||||
return @{}
|
||||
}
|
||||
}
|
||||
|
||||
# Safely get JSON field with fallback
|
||||
function Get-JsonField {
|
||||
param(
|
||||
[PSObject]$Json,
|
||||
[string]$Field,
|
||||
[string]$Fallback = ""
|
||||
)
|
||||
|
||||
if ($null -eq $Json) {
|
||||
return $Fallback
|
||||
}
|
||||
|
||||
# Handle array access syntax (e.g., "workspace_roots[0]")
|
||||
if ($Field -match '^(.+)\[(\d+)\]$') {
|
||||
$arrayField = $Matches[1]
|
||||
$index = [int]$Matches[2]
|
||||
|
||||
if ($Json.PSObject.Properties.Name -contains $arrayField) {
|
||||
$array = $Json.$arrayField
|
||||
if ($null -ne $array -and $array.Count -gt $index) {
|
||||
$value = $array[$index]
|
||||
if (-not (Test-IsEmpty $value)) {
|
||||
return $value
|
||||
}
|
||||
}
|
||||
}
|
||||
return $Fallback
|
||||
}
|
||||
|
||||
# Simple field access
|
||||
if ($Json.PSObject.Properties.Name -contains $Field) {
|
||||
$value = $Json.$Field
|
||||
if (-not (Test-IsEmpty $value)) {
|
||||
return $value
|
||||
}
|
||||
}
|
||||
|
||||
return $Fallback
|
||||
}
|
||||
|
||||
# Convert object to JSON string (compact)
|
||||
function ConvertTo-JsonCompact {
|
||||
param([object]$Object)
|
||||
|
||||
return $Object | ConvertTo-Json -Compress -Depth 10
|
||||
}
|
||||
|
||||
# Send HTTP POST request (fire-and-forget style)
|
||||
function Send-HttpPostAsync {
|
||||
param(
|
||||
[string]$Uri,
|
||||
[object]$Body
|
||||
)
|
||||
|
||||
try {
|
||||
$bodyJson = ConvertTo-JsonCompact $Body
|
||||
Start-Job -ScriptBlock {
|
||||
param($u, $b)
|
||||
try {
|
||||
Invoke-RestMethod -Uri $u -Method Post -Body $b -ContentType "application/json" -TimeoutSec 5 -ErrorAction SilentlyContinue | Out-Null
|
||||
} catch {}
|
||||
} -ArgumentList $Uri, $bodyJson | Out-Null
|
||||
} catch {
|
||||
# Ignore errors - fire and forget
|
||||
}
|
||||
}
|
||||
|
||||
# Send HTTP POST request (synchronous)
|
||||
function Send-HttpPost {
|
||||
param(
|
||||
[string]$Uri,
|
||||
[object]$Body
|
||||
)
|
||||
|
||||
try {
|
||||
$bodyJson = ConvertTo-JsonCompact $Body
|
||||
Invoke-RestMethod -Uri $u -Method Post -Body $bodyJson -ContentType "application/json" -TimeoutSec 5 -ErrorAction SilentlyContinue | Out-Null
|
||||
} catch {
|
||||
# Ignore errors
|
||||
}
|
||||
}
|
||||
|
||||
# Get HTTP response
|
||||
function Get-HttpResponse {
|
||||
param(
|
||||
[string]$Uri,
|
||||
[int]$TimeoutSec = 5
|
||||
)
|
||||
|
||||
try {
|
||||
return Invoke-RestMethod -Uri $Uri -Method Get -TimeoutSec $TimeoutSec -ErrorAction Stop
|
||||
} catch {
|
||||
return $null
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Common utility functions for Cursor hooks
|
||||
# Source this file in hook scripts: source "$(dirname "$0")/common.sh"
|
||||
|
||||
# Check if required commands exist
|
||||
check_dependencies() {
|
||||
local missing=()
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
missing+=("jq")
|
||||
fi
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
missing+=("curl")
|
||||
fi
|
||||
|
||||
if [ ${#missing[@]} -gt 0 ]; then
|
||||
echo "Error: Missing required dependencies: ${missing[*]}" >&2
|
||||
echo "Please install: ${missing[*]}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Safely read JSON from stdin with error handling
|
||||
read_json_input() {
|
||||
local input
|
||||
input=$(cat 2>/dev/null || echo "{}")
|
||||
|
||||
# Validate JSON
|
||||
if ! echo "$input" | jq empty 2>/dev/null; then
|
||||
# Invalid JSON - return empty object
|
||||
echo "{}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "$input"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get worker port from settings with validation
|
||||
get_worker_port() {
|
||||
local data_dir="${HOME}/.claude-mem"
|
||||
local settings_file="${data_dir}/settings.json"
|
||||
local port="37777"
|
||||
|
||||
if [ -f "$settings_file" ]; then
|
||||
local parsed_port
|
||||
parsed_port=$(jq -r '.CLAUDE_MEM_WORKER_PORT // "37777"' "$settings_file" 2>/dev/null || echo "37777")
|
||||
|
||||
# Validate port is a number between 1-65535
|
||||
if [[ "$parsed_port" =~ ^[0-9]+$ ]] && [ "$parsed_port" -ge 1 ] && [ "$parsed_port" -le 65535 ]; then
|
||||
port="$parsed_port"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$port"
|
||||
}
|
||||
|
||||
# Ensure worker is running with retries
|
||||
ensure_worker_running() {
|
||||
local port="${1:-37777}"
|
||||
local max_retries="${2:-75}" # 15 seconds total (75 * 0.2s)
|
||||
local retry_count=0
|
||||
|
||||
while [ $retry_count -lt $max_retries ]; do
|
||||
if curl -s -f "http://127.0.0.1:${port}/api/readiness" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 0.2
|
||||
retry_count=$((retry_count + 1))
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# URL encode a string (basic implementation)
|
||||
url_encode() {
|
||||
local string="$1"
|
||||
# Use printf to URL encode
|
||||
printf '%s' "$string" | jq -sRr @uri
|
||||
}
|
||||
|
||||
# Get project name from workspace root
|
||||
get_project_name() {
|
||||
local workspace_root="$1"
|
||||
|
||||
if [ -z "$workspace_root" ]; then
|
||||
echo "unknown-project"
|
||||
return
|
||||
fi
|
||||
|
||||
# Use basename, fallback to unknown-project
|
||||
local project_name
|
||||
project_name=$(basename "$workspace_root" 2>/dev/null || echo "unknown-project")
|
||||
|
||||
# Handle edge case: empty basename (root directory)
|
||||
if [ -z "$project_name" ]; then
|
||||
# Check if it's a Windows drive root
|
||||
if [[ "$workspace_root" =~ ^[A-Za-z]:\\?$ ]]; then
|
||||
local drive_letter
|
||||
drive_letter=$(echo "$workspace_root" | grep -oE '^[A-Za-z]' | tr '[:lower:]' '[:upper:]')
|
||||
echo "drive-${drive_letter}"
|
||||
else
|
||||
echo "unknown-project"
|
||||
fi
|
||||
else
|
||||
echo "$project_name"
|
||||
fi
|
||||
}
|
||||
|
||||
# Safely extract JSON field with fallback
|
||||
# Supports both simple fields (e.g., "conversation_id") and array access (e.g., "workspace_roots[0]")
|
||||
json_get() {
|
||||
local json="$1"
|
||||
local field="$2"
|
||||
local fallback="${3:-}"
|
||||
|
||||
local value
|
||||
|
||||
# Handle array access syntax (e.g., "workspace_roots[0]")
|
||||
if [[ "$field" =~ ^(.+)\[([0-9]+)\]$ ]]; then
|
||||
local array_field="${BASH_REMATCH[1]}"
|
||||
local index="${BASH_REMATCH[2]}"
|
||||
value=$(echo "$json" | jq -r --arg f "$array_field" --arg i "$index" --arg fb "$fallback" '.[$f] // [] | .[$i | tonumber] // $fb' 2>/dev/null || echo "$fallback")
|
||||
else
|
||||
# Simple field access
|
||||
value=$(echo "$json" | jq -r --arg f "$field" --arg fb "$fallback" '.[$f] // $fb' 2>/dev/null || echo "$fallback")
|
||||
fi
|
||||
|
||||
echo "$value"
|
||||
}
|
||||
|
||||
# Check if string is empty or null
|
||||
is_empty() {
|
||||
local str="$1"
|
||||
[ -z "$str" ] || [ "$str" = "null" ] || [ "$str" = "empty" ]
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
# Context Hook for Cursor (beforeSubmitPrompt) - PowerShell
|
||||
# Ensures worker is running and refreshes context before prompt submission
|
||||
#
|
||||
# Context is updated in BOTH places:
|
||||
# - Here (beforeSubmitPrompt): Fresh context at session start
|
||||
# - stop hook (session-summary.ps1): Updated context after observations are made
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Source common utilities
|
||||
$commonPath = Join-Path $PSScriptRoot "common.ps1"
|
||||
if (Test-Path $commonPath) {
|
||||
. $commonPath
|
||||
} else {
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Read JSON input from stdin
|
||||
$input = Read-JsonInput
|
||||
|
||||
# Extract workspace root
|
||||
$workspaceRoot = Get-JsonField $input "workspace_roots[0]" ""
|
||||
if (Test-IsEmpty $workspaceRoot) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Get project name
|
||||
$projectName = Get-ProjectName $workspaceRoot
|
||||
|
||||
# Get worker port from settings
|
||||
$workerPort = Get-WorkerPort
|
||||
|
||||
# Ensure worker is running (with retries)
|
||||
# This primes the worker before the session starts
|
||||
if (Test-WorkerReady -Port $workerPort) {
|
||||
# Refresh context file with latest observations
|
||||
$projectEncoded = Get-UrlEncodedString $projectName
|
||||
$contextUri = "http://127.0.0.1:$workerPort/api/context/inject?project=$projectEncoded"
|
||||
$context = Get-HttpResponse -Uri $contextUri
|
||||
|
||||
if (-not [string]::IsNullOrEmpty($context)) {
|
||||
$rulesDir = Join-Path $workspaceRoot ".cursor\rules"
|
||||
$rulesFile = Join-Path $rulesDir "claude-mem-context.mdc"
|
||||
|
||||
# Create rules directory if it doesn't exist
|
||||
if (-not (Test-Path $rulesDir)) {
|
||||
New-Item -ItemType Directory -Path $rulesDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# Write context as a Cursor rule with alwaysApply: true
|
||||
$ruleContent = @"
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Claude-mem context from past sessions (auto-updated)"
|
||||
---
|
||||
|
||||
# Memory Context from Past Sessions
|
||||
|
||||
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
||||
|
||||
$context
|
||||
|
||||
---
|
||||
*Updated after last session. Use claude-mem's MCP search tools for more detailed queries.*
|
||||
"@
|
||||
|
||||
Set-Content -Path $rulesFile -Value $ruleContent -Encoding UTF8 -Force
|
||||
}
|
||||
}
|
||||
|
||||
# Allow prompt to continue
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Context Hook for Cursor (beforeSubmitPrompt)
|
||||
# Ensures worker is running and refreshes context before prompt submission
|
||||
#
|
||||
# Context is updated in BOTH places:
|
||||
# - Here (beforeSubmitPrompt): Fresh context at session start
|
||||
# - stop hook (session-summary.sh): Updated context after observations are made
|
||||
|
||||
# Source common utilities
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/common.sh" 2>/dev/null || {
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check dependencies (non-blocking)
|
||||
check_dependencies >/dev/null 2>&1 || true
|
||||
|
||||
# Read JSON input from stdin
|
||||
input=$(read_json_input)
|
||||
|
||||
# Extract workspace root
|
||||
workspace_root=$(json_get "$input" "workspace_roots[0]" "")
|
||||
if is_empty "$workspace_root"; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Get project name
|
||||
project_name=$(get_project_name "$workspace_root")
|
||||
|
||||
# Get worker port from settings
|
||||
worker_port=$(get_worker_port)
|
||||
|
||||
# Ensure worker is running (with retries)
|
||||
# This primes the worker before the session starts
|
||||
if ensure_worker_running "$worker_port" >/dev/null 2>&1; then
|
||||
# Refresh context file with latest observations
|
||||
project_encoded=$(url_encode "$project_name")
|
||||
context=$(curl -s -f "http://127.0.0.1:${worker_port}/api/context/inject?project=${project_encoded}" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$context" ]; then
|
||||
rules_dir="${workspace_root}/.cursor/rules"
|
||||
rules_file="${rules_dir}/claude-mem-context.mdc"
|
||||
|
||||
# Create rules directory if it doesn't exist
|
||||
mkdir -p "$rules_dir" 2>/dev/null || true
|
||||
|
||||
# Write context as a Cursor rule with alwaysApply: true
|
||||
cat > "$rules_file" 2>/dev/null << EOF
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Claude-mem context from past sessions (auto-updated)"
|
||||
---
|
||||
|
||||
# Memory Context from Past Sessions
|
||||
|
||||
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
||||
|
||||
${context}
|
||||
|
||||
---
|
||||
*Updated after last session. Use claude-mem's MCP search tools for more detailed queries.*
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
# Allow prompt to continue
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Installation script for claude-mem Cursor hooks
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
INSTALL_TYPE="${1:-user}" # 'user' (recommended) or 'project'
|
||||
|
||||
echo "Installing claude-mem Cursor hooks (${INSTALL_TYPE} level)..."
|
||||
|
||||
case "$INSTALL_TYPE" in
|
||||
"project")
|
||||
if [ ! -d ".cursor" ]; then
|
||||
mkdir -p .cursor
|
||||
fi
|
||||
TARGET_DIR=".cursor"
|
||||
HOOKS_DIR=".cursor/hooks"
|
||||
;;
|
||||
"user")
|
||||
TARGET_DIR="${HOME}/.cursor"
|
||||
HOOKS_DIR="${HOME}/.cursor/hooks"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid install type: $INSTALL_TYPE"
|
||||
echo "Usage: $0 [user (recommended)|project]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Create hooks directory
|
||||
mkdir -p "$HOOKS_DIR"
|
||||
|
||||
# Copy hook scripts
|
||||
echo "Copying hook scripts..."
|
||||
cp "$SCRIPT_DIR"/*.sh "$HOOKS_DIR/"
|
||||
chmod +x "$HOOKS_DIR"/*.sh
|
||||
|
||||
# Copy hooks.json
|
||||
echo "Copying hooks.json..."
|
||||
cp "$SCRIPT_DIR/hooks.json" "$TARGET_DIR/hooks.json"
|
||||
|
||||
# Update paths in hooks.json if needed
|
||||
# Use portable sed approach that works on both BSD (macOS) and GNU (Linux) sed
|
||||
if [ "$INSTALL_TYPE" = "project" ]; then
|
||||
# For project-level, paths should be relative
|
||||
# Create temp file, modify, then move (portable across sed variants)
|
||||
tmp_file=$(mktemp)
|
||||
sed 's|\./cursor-hooks/|\./\.cursor/hooks/|g' "$TARGET_DIR/hooks.json" > "$tmp_file"
|
||||
mv "$tmp_file" "$TARGET_DIR/hooks.json"
|
||||
else
|
||||
# For user-level, use absolute paths
|
||||
tmp_file=$(mktemp)
|
||||
sed "s|\./cursor-hooks/|${HOOKS_DIR}/|g" "$TARGET_DIR/hooks.json" > "$tmp_file"
|
||||
mv "$tmp_file" "$TARGET_DIR/hooks.json"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✓ Installation complete!"
|
||||
echo ""
|
||||
echo "Hooks installed to: $TARGET_DIR/hooks.json"
|
||||
echo "Scripts installed to: $HOOKS_DIR"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Ensure claude-mem worker is running:"
|
||||
echo " cd ~/.claude/plugins/marketplaces/thedotmack && npm run worker:start"
|
||||
echo ""
|
||||
echo "2. Restart Cursor to load the hooks"
|
||||
echo ""
|
||||
echo "3. Check Cursor Settings → Hooks tab to verify hooks are active"
|
||||
echo ""
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# Save File Edit Hook for Cursor (PowerShell)
|
||||
# Captures file edits made by the agent
|
||||
# Maps file edits to claude-mem observations
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Source common utilities
|
||||
$commonPath = Join-Path $PSScriptRoot "common.ps1"
|
||||
if (Test-Path $commonPath) {
|
||||
. $commonPath
|
||||
} else {
|
||||
Write-Warning "common.ps1 not found, using fallback functions"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
$input = Read-JsonInput
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
$conversationId = Get-JsonField $input "conversation_id" ""
|
||||
$generationId = Get-JsonField $input "generation_id" ""
|
||||
$filePath = Get-JsonField $input "file_path" ""
|
||||
$workspaceRoot = Get-JsonField $input "workspace_roots[0]" ""
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if (Test-IsEmpty $workspaceRoot) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Exit if no file_path
|
||||
if (Test-IsEmpty $filePath) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Use conversation_id as session_id, fallback to generation_id
|
||||
$sessionId = $conversationId
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
$sessionId = $generationId
|
||||
}
|
||||
|
||||
# Exit if no session_id available
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Get worker port from settings with validation
|
||||
$workerPort = Get-WorkerPort
|
||||
|
||||
# Extract edits array, defaulting to [] if invalid
|
||||
$edits = @()
|
||||
if ($input.PSObject.Properties.Name -contains "edits") {
|
||||
$edits = $input.edits
|
||||
if ($null -eq $edits -or -not ($edits -is [array])) {
|
||||
$edits = @()
|
||||
}
|
||||
}
|
||||
|
||||
# Exit if no edits
|
||||
if ($edits.Count -eq 0) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Create a summary of the edits for the observation
|
||||
$editSummaries = @()
|
||||
foreach ($edit in $edits) {
|
||||
$oldStr = ""
|
||||
$newStr = ""
|
||||
|
||||
if ($edit.PSObject.Properties.Name -contains "old_string") {
|
||||
$oldStr = $edit.old_string
|
||||
if ($oldStr.Length -gt 50) {
|
||||
$oldStr = $oldStr.Substring(0, 50) + "..."
|
||||
}
|
||||
}
|
||||
|
||||
if ($edit.PSObject.Properties.Name -contains "new_string") {
|
||||
$newStr = $edit.new_string
|
||||
if ($newStr.Length -gt 50) {
|
||||
$newStr = $newStr.Substring(0, 50) + "..."
|
||||
}
|
||||
}
|
||||
|
||||
$editSummaries += "$oldStr → $newStr"
|
||||
}
|
||||
|
||||
$editSummary = $editSummaries -join "; "
|
||||
if ([string]::IsNullOrEmpty($editSummary)) {
|
||||
$editSummary = "File edited"
|
||||
}
|
||||
|
||||
# Treat file edits as a "write_file" tool usage
|
||||
$toolInput = @{
|
||||
file_path = $filePath
|
||||
edits = $edits
|
||||
}
|
||||
|
||||
$toolResponse = @{
|
||||
success = $true
|
||||
summary = $editSummary
|
||||
}
|
||||
|
||||
$payload = @{
|
||||
contentSessionId = $sessionId
|
||||
tool_name = "write_file"
|
||||
tool_input = $toolInput
|
||||
tool_response = $toolResponse
|
||||
cwd = $workspaceRoot
|
||||
}
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if (-not (Test-WorkerReady -Port $workerPort)) {
|
||||
# Worker not ready - exit gracefully (don't block Cursor)
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Send observation to claude-mem worker (fire-and-forget)
|
||||
$uri = "http://127.0.0.1:$workerPort/api/sessions/observations"
|
||||
|
||||
try {
|
||||
$bodyJson = ConvertTo-JsonCompact $payload
|
||||
Invoke-RestMethod -Uri $uri -Method Post -Body $bodyJson -ContentType "application/json" -TimeoutSec 5 -ErrorAction SilentlyContinue | Out-Null
|
||||
} catch {
|
||||
# Ignore errors - don't block Cursor
|
||||
}
|
||||
|
||||
exit 0
|
||||
@@ -1,112 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Save File Edit Hook for Cursor
|
||||
# Captures file edits made by the agent
|
||||
# Maps file edits to claude-mem observations
|
||||
|
||||
# Source common utilities
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/common.sh" 2>/dev/null || {
|
||||
echo "Warning: common.sh not found, using fallback functions" >&2
|
||||
}
|
||||
|
||||
# Check dependencies (non-blocking)
|
||||
check_dependencies >/dev/null 2>&1 || true
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
input=$(read_json_input)
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
conversation_id=$(json_get "$input" "conversation_id" "")
|
||||
generation_id=$(json_get "$input" "generation_id" "")
|
||||
file_path=$(json_get "$input" "file_path" "")
|
||||
workspace_root=$(json_get "$input" "workspace_roots[0]" "")
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if is_empty "$workspace_root"; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Exit if no file_path
|
||||
if is_empty "$file_path"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Use conversation_id as session_id, fallback to generation_id
|
||||
session_id="$conversation_id"
|
||||
if is_empty "$session_id"; then
|
||||
session_id="$generation_id"
|
||||
fi
|
||||
|
||||
# Exit if no session_id available
|
||||
if is_empty "$session_id"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get worker port from settings with validation
|
||||
worker_port=$(get_worker_port)
|
||||
|
||||
# Extract edits array, defaulting to [] if invalid
|
||||
edits=$(echo "$input" | jq -c '.edits // []' 2>/dev/null || echo "[]")
|
||||
|
||||
# Validate edits is a valid JSON array
|
||||
if ! echo "$edits" | jq 'type == "array"' 2>/dev/null | grep -q true; then
|
||||
edits="[]"
|
||||
fi
|
||||
|
||||
# Exit if no edits
|
||||
if [ "$edits" = "[]" ] || is_empty "$edits"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create a summary of the edits for the observation (with error handling)
|
||||
edit_summary=$(echo "$edits" | jq -r '[.[] | "\(.old_string[0:50] // "")... → \(.new_string[0:50] // "")..."] | join("; ")' 2>/dev/null || echo "File edited")
|
||||
|
||||
# Treat file edits as a "write_file" tool usage
|
||||
tool_input=$(jq -n \
|
||||
--arg path "$file_path" \
|
||||
--argjson edits "$edits" \
|
||||
'{
|
||||
file_path: $path,
|
||||
edits: $edits
|
||||
}' 2>/dev/null || echo '{}')
|
||||
|
||||
tool_response=$(jq -n \
|
||||
--arg summary "$edit_summary" \
|
||||
'{
|
||||
success: true,
|
||||
summary: $summary
|
||||
}' 2>/dev/null || echo '{}')
|
||||
|
||||
payload=$(jq -n \
|
||||
--arg sessionId "$session_id" \
|
||||
--arg cwd "$workspace_root" \
|
||||
--argjson toolInput "$tool_input" \
|
||||
--argjson toolResponse "$tool_response" \
|
||||
'{
|
||||
contentSessionId: $sessionId,
|
||||
tool_name: "write_file",
|
||||
tool_input: $toolInput,
|
||||
tool_response: $toolResponse,
|
||||
cwd: $cwd
|
||||
}' 2>/dev/null)
|
||||
|
||||
# Exit if payload creation failed
|
||||
if [ -z "$payload" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if ! ensure_worker_running "$worker_port"; then
|
||||
# Worker not ready - exit gracefully (don't block Cursor)
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Send observation to claude-mem worker (fire-and-forget)
|
||||
curl -s -X POST \
|
||||
"http://127.0.0.1:${worker_port}/api/sessions/observations" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
>/dev/null 2>&1 || true
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
# Save Observation Hook for Cursor (PowerShell)
|
||||
# Captures MCP tool usage and shell command execution
|
||||
# Maps to claude-mem's save-hook functionality
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Source common utilities
|
||||
$commonPath = Join-Path $PSScriptRoot "common.ps1"
|
||||
if (Test-Path $commonPath) {
|
||||
. $commonPath
|
||||
} else {
|
||||
Write-Warning "common.ps1 not found, using fallback functions"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
$input = Read-JsonInput
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
$conversationId = Get-JsonField $input "conversation_id" ""
|
||||
$generationId = Get-JsonField $input "generation_id" ""
|
||||
$workspaceRoot = Get-JsonField $input "workspace_roots[0]" ""
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if (Test-IsEmpty $workspaceRoot) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Use conversation_id as session_id (stable across turns), fallback to generation_id
|
||||
$sessionId = $conversationId
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
$sessionId = $generationId
|
||||
}
|
||||
|
||||
# Exit if no session_id available
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Get worker port from settings with validation
|
||||
$workerPort = Get-WorkerPort
|
||||
|
||||
# Determine hook type and extract relevant data
|
||||
$hookEvent = Get-JsonField $input "hook_event_name" ""
|
||||
|
||||
$payload = $null
|
||||
|
||||
if ($hookEvent -eq "afterMCPExecution") {
|
||||
# MCP tool execution
|
||||
$toolName = Get-JsonField $input "tool_name" ""
|
||||
|
||||
if (Test-IsEmpty $toolName) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Extract tool_input and tool_response, defaulting to {} if invalid
|
||||
$toolInput = @{}
|
||||
$toolResponse = @{}
|
||||
|
||||
if ($input.PSObject.Properties.Name -contains "tool_input") {
|
||||
$toolInput = $input.tool_input
|
||||
if ($null -eq $toolInput) { $toolInput = @{} }
|
||||
}
|
||||
|
||||
if ($input.PSObject.Properties.Name -contains "result_json") {
|
||||
$toolResponse = $input.result_json
|
||||
if ($null -eq $toolResponse) { $toolResponse = @{} }
|
||||
}
|
||||
|
||||
# Prepare observation payload
|
||||
$payload = @{
|
||||
contentSessionId = $sessionId
|
||||
tool_name = $toolName
|
||||
tool_input = $toolInput
|
||||
tool_response = $toolResponse
|
||||
cwd = $workspaceRoot
|
||||
}
|
||||
|
||||
} elseif ($hookEvent -eq "afterShellExecution") {
|
||||
# Shell command execution
|
||||
$command = Get-JsonField $input "command" ""
|
||||
|
||||
if (Test-IsEmpty $command) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
$output = Get-JsonField $input "output" ""
|
||||
|
||||
# Treat shell commands as "Bash" tool usage
|
||||
$toolInput = @{ command = $command }
|
||||
$toolResponse = @{ output = $output }
|
||||
|
||||
$payload = @{
|
||||
contentSessionId = $sessionId
|
||||
tool_name = "Bash"
|
||||
tool_input = $toolInput
|
||||
tool_response = $toolResponse
|
||||
cwd = $workspaceRoot
|
||||
}
|
||||
|
||||
} else {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Exit if payload creation failed
|
||||
if ($null -eq $payload) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if (-not (Test-WorkerReady -Port $workerPort)) {
|
||||
# Worker not ready - exit gracefully (don't block Cursor)
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Send observation to claude-mem worker (fire-and-forget)
|
||||
$uri = "http://127.0.0.1:$workerPort/api/sessions/observations"
|
||||
|
||||
try {
|
||||
$bodyJson = ConvertTo-JsonCompact $payload
|
||||
Invoke-RestMethod -Uri $uri -Method Post -Body $bodyJson -ContentType "application/json" -TimeoutSec 5 -ErrorAction SilentlyContinue | Out-Null
|
||||
} catch {
|
||||
# Ignore errors - don't block Cursor
|
||||
}
|
||||
|
||||
exit 0
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Save Observation Hook for Cursor
|
||||
# Captures MCP tool usage and shell command execution
|
||||
# Maps to claude-mem's save-hook functionality
|
||||
|
||||
# Source common utilities
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/common.sh" 2>/dev/null || {
|
||||
echo "Warning: common.sh not found, using fallback functions" >&2
|
||||
}
|
||||
|
||||
# Check dependencies (non-blocking)
|
||||
check_dependencies >/dev/null 2>&1 || true
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
input=$(read_json_input)
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
conversation_id=$(json_get "$input" "conversation_id" "")
|
||||
generation_id=$(json_get "$input" "generation_id" "")
|
||||
workspace_root=$(json_get "$input" "workspace_roots[0]" "")
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if is_empty "$workspace_root"; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Use conversation_id as session_id (stable across turns), fallback to generation_id
|
||||
session_id="$conversation_id"
|
||||
if is_empty "$session_id"; then
|
||||
session_id="$generation_id"
|
||||
fi
|
||||
|
||||
# Exit if no session_id available
|
||||
if is_empty "$session_id"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get worker port from settings with validation
|
||||
worker_port=$(get_worker_port)
|
||||
|
||||
# Determine hook type and extract relevant data
|
||||
hook_event=$(json_get "$input" "hook_event_name" "")
|
||||
|
||||
if [ "$hook_event" = "afterMCPExecution" ]; then
|
||||
# MCP tool execution
|
||||
tool_name=$(json_get "$input" "tool_name" "")
|
||||
|
||||
if is_empty "$tool_name"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract tool_input and tool_response, defaulting to {} if invalid
|
||||
tool_input=$(echo "$input" | jq -c '.tool_input // {}' 2>/dev/null || echo "{}")
|
||||
tool_response=$(echo "$input" | jq -c '.result_json // {}' 2>/dev/null || echo "{}")
|
||||
|
||||
# Validate JSON
|
||||
if ! echo "$tool_input" | jq empty 2>/dev/null; then
|
||||
tool_input="{}"
|
||||
fi
|
||||
if ! echo "$tool_response" | jq empty 2>/dev/null; then
|
||||
tool_response="{}"
|
||||
fi
|
||||
|
||||
# Prepare observation payload
|
||||
payload=$(jq -n \
|
||||
--arg sessionId "$session_id" \
|
||||
--arg toolName "$tool_name" \
|
||||
--argjson toolInput "$tool_input" \
|
||||
--argjson toolResponse "$tool_response" \
|
||||
--arg cwd "$workspace_root" \
|
||||
'{
|
||||
contentSessionId: $sessionId,
|
||||
tool_name: $toolName,
|
||||
tool_input: $toolInput,
|
||||
tool_response: $toolResponse,
|
||||
cwd: $cwd
|
||||
}' 2>/dev/null)
|
||||
|
||||
elif [ "$hook_event" = "afterShellExecution" ]; then
|
||||
# Shell command execution
|
||||
command=$(json_get "$input" "command" "")
|
||||
|
||||
if is_empty "$command"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
output=$(json_get "$input" "output" "")
|
||||
|
||||
# Treat shell commands as "Bash" tool usage
|
||||
tool_input=$(jq -n --arg cmd "$command" '{command: $cmd}' 2>/dev/null || echo '{}')
|
||||
tool_response=$(jq -n --arg out "$output" '{output: $out}' 2>/dev/null || echo '{}')
|
||||
|
||||
payload=$(jq -n \
|
||||
--arg sessionId "$session_id" \
|
||||
--arg cwd "$workspace_root" \
|
||||
--argjson toolInput "$tool_input" \
|
||||
--argjson toolResponse "$tool_response" \
|
||||
'{
|
||||
contentSessionId: $sessionId,
|
||||
tool_name: "Bash",
|
||||
tool_input: $toolInput,
|
||||
tool_response: $toolResponse,
|
||||
cwd: $cwd
|
||||
}' 2>/dev/null)
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Exit if payload creation failed
|
||||
if [ -z "$payload" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if ! ensure_worker_running "$worker_port"; then
|
||||
# Worker not ready - exit gracefully (don't block Cursor)
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Send observation to claude-mem worker (fire-and-forget)
|
||||
curl -s -X POST \
|
||||
"http://127.0.0.1:${worker_port}/api/sessions/observations" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
>/dev/null 2>&1 || true
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
# Session Initialization Hook for Cursor (PowerShell)
|
||||
# Maps to claude-mem's new-hook functionality
|
||||
# Initializes a new session when a prompt is submitted
|
||||
#
|
||||
# NOTE: This hook runs as part of beforeSubmitPrompt and MUST output valid JSON
|
||||
# with at least {"continue": true} to allow prompt submission.
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Source common utilities
|
||||
$commonPath = Join-Path $PSScriptRoot "common.ps1"
|
||||
if (Test-Path $commonPath) {
|
||||
. $commonPath
|
||||
} else {
|
||||
# Fallback - output continue and exit
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
$input = Read-JsonInput
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
$conversationId = Get-JsonField $input "conversation_id" ""
|
||||
$generationId = Get-JsonField $input "generation_id" ""
|
||||
$prompt = Get-JsonField $input "prompt" ""
|
||||
$workspaceRoot = Get-JsonField $input "workspace_roots[0]" ""
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if (Test-IsEmpty $workspaceRoot) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Get project name from workspace root
|
||||
$projectName = Get-ProjectName $workspaceRoot
|
||||
|
||||
# Use conversation_id as session_id (stable across turns), fallback to generation_id
|
||||
$sessionId = $conversationId
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
$sessionId = $generationId
|
||||
}
|
||||
|
||||
# Exit gracefully if no session_id available (still allow prompt)
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Get worker port from settings with validation
|
||||
$workerPort = Get-WorkerPort
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if (-not (Test-WorkerReady -Port $workerPort)) {
|
||||
# Worker not ready - still allow prompt to continue
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Strip leading slash from commands for memory agent (parity with new-hook.ts)
|
||||
# /review 101 → review 101 (more semantic for observations)
|
||||
$cleanedPrompt = $prompt
|
||||
if (-not [string]::IsNullOrEmpty($prompt) -and $prompt.StartsWith("/")) {
|
||||
$cleanedPrompt = $prompt.Substring(1)
|
||||
}
|
||||
|
||||
# Initialize session via HTTP - handles DB operations and privacy checks
|
||||
$payload = @{
|
||||
contentSessionId = $sessionId
|
||||
project = $projectName
|
||||
prompt = $cleanedPrompt
|
||||
}
|
||||
|
||||
# Send request to worker (fire-and-forget, don't wait for response)
|
||||
$uri = "http://127.0.0.1:$workerPort/api/sessions/init"
|
||||
Send-HttpPostAsync -Uri $uri -Body $payload
|
||||
|
||||
# Always allow prompt to continue
|
||||
Write-Output '{"continue": true}'
|
||||
exit 0
|
||||
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Session Initialization Hook for Cursor
|
||||
# Maps to claude-mem's new-hook functionality
|
||||
# Initializes a new session when a prompt is submitted
|
||||
#
|
||||
# NOTE: This hook runs as part of beforeSubmitPrompt and MUST output valid JSON
|
||||
# with at least {"continue": true} to allow prompt submission.
|
||||
|
||||
# Source common utilities
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/common.sh" 2>/dev/null || {
|
||||
# Fallback - output continue and exit
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check dependencies (non-blocking - just warn)
|
||||
check_dependencies >/dev/null 2>&1 || true
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
input=$(read_json_input)
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
conversation_id=$(json_get "$input" "conversation_id" "")
|
||||
generation_id=$(json_get "$input" "generation_id" "")
|
||||
prompt=$(json_get "$input" "prompt" "")
|
||||
workspace_root=$(json_get "$input" "workspace_roots[0]" "")
|
||||
|
||||
# Fallback to current directory if no workspace root
|
||||
if is_empty "$workspace_root"; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Get project name from workspace root
|
||||
project_name=$(get_project_name "$workspace_root")
|
||||
|
||||
# Use conversation_id as session_id (stable across turns), fallback to generation_id
|
||||
session_id="$conversation_id"
|
||||
if is_empty "$session_id"; then
|
||||
session_id="$generation_id"
|
||||
fi
|
||||
|
||||
# Exit gracefully if no session_id available (still allow prompt)
|
||||
if is_empty "$session_id"; then
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get worker port from settings with validation
|
||||
worker_port=$(get_worker_port)
|
||||
|
||||
# Ensure worker is running (with retries like claude-mem hooks)
|
||||
if ! ensure_worker_running "$worker_port"; then
|
||||
# Worker not ready - still allow prompt to continue
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Strip leading slash from commands for memory agent (parity with new-hook.ts)
|
||||
# /review 101 → review 101 (more semantic for observations)
|
||||
cleaned_prompt="$prompt"
|
||||
if [ -n "$prompt" ] && [ "${prompt:0:1}" = "/" ]; then
|
||||
cleaned_prompt="${prompt:1}"
|
||||
fi
|
||||
|
||||
# Initialize session via HTTP - handles DB operations and privacy checks
|
||||
payload=$(jq -n \
|
||||
--arg sessionId "$session_id" \
|
||||
--arg project "$project_name" \
|
||||
--arg promptText "$cleaned_prompt" \
|
||||
'{
|
||||
contentSessionId: $sessionId,
|
||||
project: $project,
|
||||
prompt: $promptText
|
||||
}' 2>/dev/null)
|
||||
|
||||
# Exit if payload creation failed (still allow prompt)
|
||||
if [ -z "$payload" ]; then
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Send request to worker (fire-and-forget, don't wait for response)
|
||||
curl -s -X POST \
|
||||
"http://127.0.0.1:${worker_port}/api/sessions/init" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
>/dev/null 2>&1 &
|
||||
|
||||
# Always allow prompt to continue
|
||||
echo '{"continue": true}'
|
||||
exit 0
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
# Session Summary Hook for Cursor (stop) - PowerShell
|
||||
# Called when agent loop ends
|
||||
#
|
||||
# This hook:
|
||||
# 1. Generates session summary
|
||||
# 2. Updates context file for next session
|
||||
#
|
||||
# Output: Empty JSON {} or {"followup_message": "..."} for auto-iteration
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Source common utilities
|
||||
$commonPath = Join-Path $PSScriptRoot "common.ps1"
|
||||
if (Test-Path $commonPath) {
|
||||
. $commonPath
|
||||
} else {
|
||||
Write-Output '{}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
$input = Read-JsonInput
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
$conversationId = Get-JsonField $input "conversation_id" ""
|
||||
$generationId = Get-JsonField $input "generation_id" ""
|
||||
$workspaceRoot = Get-JsonField $input "workspace_roots[0]" ""
|
||||
$status = Get-JsonField $input "status" "completed"
|
||||
|
||||
# Fallback workspace to current directory
|
||||
if (Test-IsEmpty $workspaceRoot) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Get project name
|
||||
$projectName = Get-ProjectName $workspaceRoot
|
||||
|
||||
# Use conversation_id as session_id, fallback to generation_id
|
||||
$sessionId = $conversationId
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
$sessionId = $generationId
|
||||
}
|
||||
|
||||
# Exit if no session_id available
|
||||
if (Test-IsEmpty $sessionId) {
|
||||
Write-Output '{}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Get worker port from settings with validation
|
||||
$workerPort = Get-WorkerPort
|
||||
|
||||
# Ensure worker is running (with retries)
|
||||
if (-not (Test-WorkerReady -Port $workerPort)) {
|
||||
Write-Output '{}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# 1. Request summary generation (fire-and-forget)
|
||||
# Note: Cursor doesn't provide transcript_path like Claude Code does,
|
||||
# so we can't extract last_user_message and last_assistant_message.
|
||||
$summaryPayload = @{
|
||||
contentSessionId = $sessionId
|
||||
last_user_message = ""
|
||||
last_assistant_message = ""
|
||||
}
|
||||
|
||||
$summaryUri = "http://127.0.0.1:$workerPort/api/sessions/summarize"
|
||||
Send-HttpPostAsync -Uri $summaryUri -Body $summaryPayload
|
||||
|
||||
# 2. Update context file for next session
|
||||
# Fetch fresh context (includes observations from this session)
|
||||
$projectEncoded = Get-UrlEncodedString $projectName
|
||||
$contextUri = "http://127.0.0.1:$workerPort/api/context/inject?project=$projectEncoded"
|
||||
$context = Get-HttpResponse -Uri $contextUri
|
||||
|
||||
if (-not [string]::IsNullOrEmpty($context)) {
|
||||
$rulesDir = Join-Path $workspaceRoot ".cursor\rules"
|
||||
$rulesFile = Join-Path $rulesDir "claude-mem-context.mdc"
|
||||
|
||||
# Create rules directory if it doesn't exist
|
||||
if (-not (Test-Path $rulesDir)) {
|
||||
New-Item -ItemType Directory -Path $rulesDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# Write context as a Cursor rule with alwaysApply: true
|
||||
$ruleContent = @"
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Claude-mem context from past sessions (auto-updated)"
|
||||
---
|
||||
|
||||
# Memory Context from Past Sessions
|
||||
|
||||
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
||||
|
||||
$context
|
||||
|
||||
---
|
||||
*Updated after last session. Use claude-mem's MCP search tools for more detailed queries.*
|
||||
"@
|
||||
|
||||
Set-Content -Path $rulesFile -Value $ruleContent -Encoding UTF8 -Force
|
||||
}
|
||||
|
||||
# Output empty JSON - no followup message
|
||||
Write-Output '{}'
|
||||
exit 0
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Session Summary Hook for Cursor (stop)
|
||||
# Called when agent loop ends
|
||||
#
|
||||
# This hook:
|
||||
# 1. Generates session summary
|
||||
# 2. Updates context file for next session
|
||||
#
|
||||
# Output: Empty JSON {} or {"followup_message": "..."} for auto-iteration
|
||||
|
||||
# Source common utilities
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "${SCRIPT_DIR}/common.sh" 2>/dev/null || {
|
||||
echo '{}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check dependencies (non-blocking)
|
||||
check_dependencies >/dev/null 2>&1 || true
|
||||
|
||||
# Read JSON input from stdin with error handling
|
||||
input=$(read_json_input)
|
||||
|
||||
# Extract common fields with safe fallbacks
|
||||
conversation_id=$(json_get "$input" "conversation_id" "")
|
||||
generation_id=$(json_get "$input" "generation_id" "")
|
||||
workspace_root=$(json_get "$input" "workspace_roots[0]" "")
|
||||
status=$(json_get "$input" "status" "completed")
|
||||
|
||||
# Fallback workspace to current directory
|
||||
if is_empty "$workspace_root"; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Get project name
|
||||
project_name=$(get_project_name "$workspace_root")
|
||||
|
||||
# Use conversation_id as session_id, fallback to generation_id
|
||||
session_id="$conversation_id"
|
||||
if is_empty "$session_id"; then
|
||||
session_id="$generation_id"
|
||||
fi
|
||||
|
||||
# Exit if no session_id available
|
||||
if is_empty "$session_id"; then
|
||||
echo '{}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Get worker port from settings with validation
|
||||
worker_port=$(get_worker_port)
|
||||
|
||||
# Ensure worker is running (with retries)
|
||||
if ! ensure_worker_running "$worker_port"; then
|
||||
echo '{}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 1. Request summary generation (fire-and-forget)
|
||||
# Note: Cursor doesn't provide transcript_path like Claude Code does,
|
||||
# so we can't extract last_user_message and last_assistant_message.
|
||||
payload=$(jq -n \
|
||||
--arg sessionId "$session_id" \
|
||||
'{
|
||||
contentSessionId: $sessionId,
|
||||
last_user_message: "",
|
||||
last_assistant_message: ""
|
||||
}' 2>/dev/null)
|
||||
|
||||
if [ -n "$payload" ]; then
|
||||
curl -s -X POST \
|
||||
"http://127.0.0.1:${worker_port}/api/sessions/summarize" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
>/dev/null 2>&1 &
|
||||
fi
|
||||
|
||||
# 2. Update context file for next session
|
||||
# Fetch fresh context (includes observations from this session)
|
||||
project_encoded=$(url_encode "$project_name")
|
||||
context=$(curl -s -f "http://127.0.0.1:${worker_port}/api/context/inject?project=${project_encoded}" 2>/dev/null || echo "")
|
||||
|
||||
if [ -n "$context" ]; then
|
||||
rules_dir="${workspace_root}/.cursor/rules"
|
||||
rules_file="${rules_dir}/claude-mem-context.mdc"
|
||||
|
||||
# Create rules directory if it doesn't exist
|
||||
mkdir -p "$rules_dir" 2>/dev/null || true
|
||||
|
||||
# Write context as a Cursor rule with alwaysApply: true
|
||||
cat > "$rules_file" 2>/dev/null << EOF
|
||||
---
|
||||
alwaysApply: true
|
||||
description: "Claude-mem context from past sessions (auto-updated)"
|
||||
---
|
||||
|
||||
# Memory Context from Past Sessions
|
||||
|
||||
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
||||
|
||||
${context}
|
||||
|
||||
---
|
||||
*Updated after last session. Use claude-mem's MCP search tools for more detailed queries.*
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Output empty JSON - no followup message
|
||||
echo '{}'
|
||||
exit 0
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# User Message Hook for Cursor (PowerShell)
|
||||
# Displays context information to the user
|
||||
# Maps to claude-mem's user-message-hook functionality
|
||||
# Note: Cursor doesn't have a direct equivalent, but we can output to stderr
|
||||
# for visibility in Cursor's output channels
|
||||
#
|
||||
# This is an OPTIONAL hook. It can be added to beforeSubmitPrompt if desired,
|
||||
# but may be verbose since it runs on every prompt submission.
|
||||
|
||||
$ErrorActionPreference = "SilentlyContinue"
|
||||
|
||||
# Read JSON input from stdin (if any)
|
||||
$inputJson = $null
|
||||
try {
|
||||
$inputText = [Console]::In.ReadToEnd()
|
||||
if (-not [string]::IsNullOrEmpty($inputText)) {
|
||||
$inputJson = $inputText | ConvertFrom-Json -ErrorAction SilentlyContinue
|
||||
}
|
||||
} catch {
|
||||
$inputJson = $null
|
||||
}
|
||||
|
||||
# Extract workspace root
|
||||
$workspaceRoot = ""
|
||||
if ($null -ne $inputJson -and $inputJson.PSObject.Properties.Name -contains "workspace_roots") {
|
||||
$wsRoots = $inputJson.workspace_roots
|
||||
if ($null -ne $wsRoots -and $wsRoots.Count -gt 0) {
|
||||
$workspaceRoot = $wsRoots[0]
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrEmpty($workspaceRoot)) {
|
||||
$workspaceRoot = Get-Location
|
||||
}
|
||||
|
||||
# Get project name
|
||||
$projectName = Split-Path $workspaceRoot -Leaf
|
||||
if ([string]::IsNullOrEmpty($projectName)) {
|
||||
$projectName = "unknown-project"
|
||||
}
|
||||
|
||||
# Get worker port from settings
|
||||
$settingsPath = Join-Path $env:USERPROFILE ".claude-mem\settings.json"
|
||||
$workerPort = 37777
|
||||
|
||||
if (Test-Path $settingsPath) {
|
||||
try {
|
||||
$settings = Get-Content $settingsPath -Raw | ConvertFrom-Json
|
||||
if ($settings.CLAUDE_MEM_WORKER_PORT) {
|
||||
$workerPort = [int]$settings.CLAUDE_MEM_WORKER_PORT
|
||||
}
|
||||
} catch {
|
||||
# Use default
|
||||
}
|
||||
}
|
||||
|
||||
# Ensure worker is running
|
||||
$maxRetries = 75
|
||||
$workerReady = $false
|
||||
|
||||
for ($i = 0; $i -lt $maxRetries; $i++) {
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "http://127.0.0.1:$workerPort/api/readiness" -Method Get -TimeoutSec 1 -ErrorAction Stop
|
||||
$workerReady = $true
|
||||
break
|
||||
} catch {
|
||||
Start-Sleep -Milliseconds 200
|
||||
}
|
||||
}
|
||||
|
||||
# If worker not ready, exit silently
|
||||
if (-not $workerReady) {
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Fetch formatted context from worker API (with colors)
|
||||
$projectEncoded = [System.Uri]::EscapeDataString($projectName)
|
||||
$contextUrl = "http://127.0.0.1:$workerPort/api/context/inject?project=$projectEncoded&colors=true"
|
||||
|
||||
$output = $null
|
||||
try {
|
||||
$output = Invoke-RestMethod -Uri $contextUrl -Method Get -TimeoutSec 5 -ErrorAction Stop
|
||||
} catch {
|
||||
$output = $null
|
||||
}
|
||||
|
||||
# Output to stderr for visibility (parity with user-message-hook.ts)
|
||||
# Note: Cursor may not display stderr the same way Claude Code does,
|
||||
# but this is the best we can do without direct UI integration
|
||||
if (-not [string]::IsNullOrEmpty($output)) {
|
||||
[Console]::Error.WriteLine("")
|
||||
[Console]::Error.WriteLine("📝 Claude-Mem Context Loaded")
|
||||
[Console]::Error.WriteLine(" ℹ️ Viewing context from past sessions")
|
||||
[Console]::Error.WriteLine("")
|
||||
[Console]::Error.WriteLine($output)
|
||||
[Console]::Error.WriteLine("")
|
||||
[Console]::Error.WriteLine("💡 Tip: Wrap content with <private> ... </private> to prevent storing sensitive information.")
|
||||
[Console]::Error.WriteLine("💬 Community: https://discord.gg/J4wttp9vDu")
|
||||
[Console]::Error.WriteLine("📺 Web Viewer: http://localhost:$workerPort/")
|
||||
[Console]::Error.WriteLine("")
|
||||
}
|
||||
|
||||
exit 0
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
# User Message Hook for Cursor
|
||||
# Displays context information to the user
|
||||
# Maps to claude-mem's user-message-hook functionality
|
||||
# Note: Cursor doesn't have a direct equivalent, but we can output to stderr
|
||||
# for visibility in Cursor's output channels
|
||||
#
|
||||
# This is an OPTIONAL hook. It can be added to beforeSubmitPrompt if desired,
|
||||
# but may be verbose since it runs on every prompt submission.
|
||||
|
||||
# Read JSON input from stdin (if any)
|
||||
input=$(cat 2>/dev/null || echo "{}")
|
||||
|
||||
# Extract workspace root
|
||||
workspace_root=$(echo "$input" | jq -r '.workspace_roots[0] // empty' 2>/dev/null || echo "")
|
||||
|
||||
if [ -z "$workspace_root" ]; then
|
||||
workspace_root=$(pwd)
|
||||
fi
|
||||
|
||||
# Get project name
|
||||
project_name=$(basename "$workspace_root" 2>/dev/null || echo "unknown-project")
|
||||
|
||||
# Get worker port from settings
|
||||
data_dir="${HOME}/.claude-mem"
|
||||
settings_file="${data_dir}/settings.json"
|
||||
worker_port="37777"
|
||||
|
||||
if [ -f "$settings_file" ]; then
|
||||
worker_port=$(jq -r '.CLAUDE_MEM_WORKER_PORT // "37777"' "$settings_file" 2>/dev/null || echo "37777")
|
||||
fi
|
||||
|
||||
# Ensure worker is running
|
||||
max_retries=75
|
||||
retry_count=0
|
||||
while [ $retry_count -lt $max_retries ]; do
|
||||
if curl -s -f "http://127.0.0.1:${worker_port}/api/readiness" > /dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 0.2
|
||||
retry_count=$((retry_count + 1))
|
||||
done
|
||||
|
||||
# If worker not ready, exit silently
|
||||
if [ $retry_count -eq $max_retries ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fetch formatted context from worker API (with colors)
|
||||
context_url="http://127.0.0.1:${worker_port}/api/context/inject?project=${project_name}&colors=true"
|
||||
output=$(curl -s -f "$context_url" 2>/dev/null || echo "")
|
||||
|
||||
# Output to stderr for visibility (parity with user-message-hook.ts)
|
||||
# Note: Cursor may not display stderr the same way Claude Code does,
|
||||
# but this is the best we can do without direct UI integration
|
||||
if [ -n "$output" ]; then
|
||||
echo "" >&2
|
||||
echo "📝 Claude-Mem Context Loaded" >&2
|
||||
echo " ℹ️ Viewing context from past sessions" >&2
|
||||
echo "" >&2
|
||||
echo "$output" >&2
|
||||
echo "" >&2
|
||||
echo "💡 Tip: Wrap content with <private> ... </private> to prevent storing sensitive information." >&2
|
||||
echo "💬 Community: https://discord.gg/J4wttp9vDu" >&2
|
||||
echo "📺 Web Viewer: http://localhost:${worker_port}/" >&2
|
||||
echo "" >&2
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<claude-mem-context>
|
||||
# Recent Activity
|
||||
|
||||
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
|
||||
|
||||
### Nov 6, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #4241 | 11:19 PM | 🟣 | Object-Oriented Architecture Design Document Created | ~662 |
|
||||
| #4240 | 11:11 PM | 🟣 | Worker Service Rewrite Blueprint Created | ~541 |
|
||||
| #4239 | 11:07 PM | 🟣 | Comprehensive Worker Service Performance Analysis Document Created | ~541 |
|
||||
| #4238 | 10:59 PM | 🔵 | Overhead Analysis Document Checked | ~203 |
|
||||
|
||||
### Nov 7, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #4609 | 6:33 PM | ✅ | PR #69 Successfully Merged to Main Branch | ~516 |
|
||||
| #4600 | 6:31 PM | 🟣 | Added Worker Service Documentation Suite | ~441 |
|
||||
| #4597 | " | 🔄 | Worker Service Refactored to Object-Oriented Architecture | ~473 |
|
||||
|
||||
### Nov 8, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #5539 | 10:20 PM | 🔵 | Harsh critical audit of context-hook reveals systematic anti-patterns | ~3154 |
|
||||
| #5497 | 9:29 PM | 🔵 | Harsh critical audit of context-hook reveals systematic anti-patterns | ~2815 |
|
||||
| #5495 | 9:28 PM | 🔵 | Context Hook Audit Reveals Project Anti-Patterns | ~660 |
|
||||
| #5476 | 9:17 PM | 🔵 | Critical Code Audit Identified 14 Anti-Patterns in Context Hook | ~887 |
|
||||
| #5391 | 8:45 PM | 🔵 | Critical Code Quality Audit of Context Hook Implementation | ~720 |
|
||||
| #5150 | 7:37 PM | 🟣 | Troubleshooting Skill Added to Claude-Mem Plugin | ~427 |
|
||||
|
||||
### Nov 9, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #6161 | 11:55 PM | 🔵 | YC W26 Application Research and Preparation Completed for Claude-Mem | ~1628 |
|
||||
| #6155 | 11:47 PM | ✅ | Comprehensive Y Combinator Winter 2026 Application Notes Created | ~1045 |
|
||||
| #5979 | 7:58 PM | 🔵 | Smart Contextualization Feature Architecture | ~560 |
|
||||
| #5971 | 7:49 PM | 🔵 | Hooks Reference Documentation Structure | ~448 |
|
||||
| #5929 | 7:08 PM | ✅ | Documentation Updates for v5.4.0 Skill-Based Search Migration | ~604 |
|
||||
| #5927 | " | ✅ | Updated Configuration Documentation for Skill-Based Search | ~497 |
|
||||
| #5920 | 7:05 PM | ✅ | Renamed Architecture Documentation File Reference | ~271 |
|
||||
|
||||
### Nov 18, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #11515 | 8:22 PM | 🔵 | Smart Contextualization Architecture Retrieved with Command Hook Pattern Details | ~502 |
|
||||
|
||||
### Dec 8, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #22294 | 9:43 PM | 🔵 | Documentation Site Structure Located | ~359 |
|
||||
|
||||
### Dec 12, 2025
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #24430 | 8:27 PM | ✅ | Removed Final Platform Check Reference from Linux Section | ~320 |
|
||||
| #24429 | " | ✅ | Final Platform Check Reference Removal from Linux Section | ~274 |
|
||||
| #24428 | " | ✅ | Corrected Second Line Number Reference for Migration Marker Logic | ~267 |
|
||||
| #24427 | 8:26 PM | ✅ | Updated Line Number Reference for PM2 Cleanup Implementation | ~260 |
|
||||
| #24426 | " | ✅ | Removed Platform Check from Manual Marker Deletion Scenario | ~338 |
|
||||
| #24425 | " | ✅ | Removed Platform Check from Fresh Install Scenario Flow | ~314 |
|
||||
| #24424 | 8:25 PM | ✅ | Renumbered Manual Marker Deletion Scenario | ~285 |
|
||||
| #24423 | " | ✅ | Renumbered Fresh Install Scenario | ~243 |
|
||||
| #24422 | " | ✅ | Removed Obsolete Windows Platform Detection Scenario | ~311 |
|
||||
| #24421 | " | ✅ | Removed Platform Check from macOS Migration Documentation | ~294 |
|
||||
| #24420 | 8:24 PM | ✅ | Platform Check Removed from Migration Documentation | ~288 |
|
||||
| #24417 | 8:16 PM | ✅ | Code Reference Example Updated to Reflect Actual Cross-Platform Implementation | ~366 |
|
||||
| #24416 | " | ✅ | Architecture Decision Documentation Updated to Reflect Cross-Platform PM2 Cleanup Rationale | ~442 |
|
||||
| #24415 | 8:15 PM | ✅ | Migration Marker Lifecycle Documentation Updated for Unified Cross-Platform Behavior | ~463 |
|
||||
| #24414 | " | ✅ | Platform Comparison Table Updated to Reflect Unified Cross-Platform Migration | ~351 |
|
||||
| #24413 | " | ✅ | Windows Platform-Specific Documentation Completely Rewritten for Unified Migration | ~428 |
|
||||
| #24412 | " | ✅ | User Experience Timeline Updated for Cross-Platform PM2 Cleanup | ~291 |
|
||||
| #24411 | 8:14 PM | ✅ | Migration Marker Lifecycle Documentation Updated for All Platforms | ~277 |
|
||||
| #24410 | " | ✅ | Marker File Platform Behavior Documentation Updated for Unified Migration | ~282 |
|
||||
| #24409 | " | ✅ | Migration Steps Documentation Updated for Cross-Platform PM2 Cleanup | ~278 |
|
||||
| #24408 | 8:13 PM | ✅ | PM2 Migration Documentation Updated to Remove Windows Platform Check | ~280 |
|
||||
</claude-mem-context>
|
||||
@@ -0,0 +1,213 @@
|
||||
# Claude-Mem PR Shipping Report
|
||||
*Generated: 2026-02-04*
|
||||
|
||||
## Executive Summary
|
||||
|
||||
6 PRs analyzed for shipping readiness. **1 is ready to merge**, 4 have conflicts, 1 is too large for easy review.
|
||||
|
||||
| PR | Title | Status | Recommendation |
|
||||
|----|-------|--------|----------------|
|
||||
| **#856** | Idle timeout for zombie processes | ✅ **MERGEABLE** | **Ship it** |
|
||||
| #700 | Windows Terminal popup fix | ⚠️ Conflicts | Rebase, then ship |
|
||||
| #722 | In-process worker architecture | ⚠️ Conflicts | Rebase, high impact |
|
||||
| #657 | generate/clean CLI commands | ⚠️ Conflicts | Rebase, then ship |
|
||||
| #863 | Ragtime email investigation | 🔍 Needs review | Research pending |
|
||||
| #464 | Sleep Agent Pipeline (contributor) | 🔴 Too large | Request split or dedicated review |
|
||||
|
||||
---
|
||||
|
||||
## Ready to Ship
|
||||
|
||||
### PR #856: Idle Timeout for Zombie Observer Processes
|
||||
**Status:** ✅ MERGEABLE (no conflicts)
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Additions | 928 |
|
||||
| Deletions | 171 |
|
||||
| Files | 8 |
|
||||
| Risk | Low-Medium |
|
||||
|
||||
**What it does:**
|
||||
- Adds 3-minute idle timeout to `SessionQueueProcessor`
|
||||
- Prevents zombie observer processes that were causing 13.4GB swap usage
|
||||
- Processes exit gracefully after inactivity instead of waiting forever
|
||||
|
||||
**Why ship it:**
|
||||
- Fixes real user-reported issue (79 zombie processes)
|
||||
- Well-tested (11 new tests, 440 lines of test coverage)
|
||||
- Clean implementation, preventive approach
|
||||
- Supersedes PR #848's reactive cleanup
|
||||
- No conflicts, ready to merge
|
||||
|
||||
**Review notes:**
|
||||
- 1 Greptile bot comment (addressed)
|
||||
- Race condition fix included
|
||||
- Enhanced logging added
|
||||
|
||||
---
|
||||
|
||||
## Needs Rebase (Have Conflicts)
|
||||
|
||||
### PR #700: Windows Terminal Popup Fix
|
||||
**Status:** ⚠️ CONFLICTING
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Additions | 187 |
|
||||
| Deletions | 399 |
|
||||
| Files | 8 |
|
||||
| Risk | Medium |
|
||||
|
||||
**What it does:**
|
||||
- Eliminates Windows Terminal popup by removing spawn-based daemon
|
||||
- Worker `start` command becomes daemon directly (no child spawn)
|
||||
- Removes `restart` command (users do `stop` then `start`)
|
||||
- Net simplification: -212 lines
|
||||
|
||||
**Breaking changes:**
|
||||
- `restart` command removed
|
||||
|
||||
**Review status:**
|
||||
- ✅ 1 APPROVAL from @volkanfirat (Jan 15, 2026)
|
||||
|
||||
**Action needed:** Resolve conflicts, then ready to ship.
|
||||
|
||||
---
|
||||
|
||||
### PR #722: In-Process Worker Architecture
|
||||
**Status:** ⚠️ CONFLICTING
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Additions | 869 |
|
||||
| Deletions | 4,658 |
|
||||
| Files | 112 |
|
||||
| Risk | High |
|
||||
|
||||
**What it does:**
|
||||
- Hook processes become the worker (no separate daemon spawning)
|
||||
- First hook that needs worker becomes the worker
|
||||
- Eliminates Windows spawn issues ("NO SPAWN" rule)
|
||||
- 761 tests pass
|
||||
|
||||
**Architectural impact:** HIGH
|
||||
- Fundamentally changes worker lifecycle
|
||||
- Hook processes stay alive (they ARE the worker)
|
||||
- First hook wins port 37777, others use HTTP
|
||||
|
||||
**Action needed:** Resolve conflicts. Consider relationship with PR #700 (both touch worker architecture).
|
||||
|
||||
---
|
||||
|
||||
### PR #657: Generate/Clean CLI Commands
|
||||
**Status:** ⚠️ CONFLICTING
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Additions | 1,184 |
|
||||
| Deletions | 5,057 |
|
||||
| Files | 104 |
|
||||
| Risk | Medium |
|
||||
|
||||
**What it does:**
|
||||
- Adds `claude-mem generate` and `claude-mem clean` CLI commands
|
||||
- Fixes validation bugs (deleted folders recreated from stale DB)
|
||||
- Fixes Windows path handling
|
||||
- Adds automatic shell alias installation
|
||||
- Disables subdirectory CLAUDE.md files by default
|
||||
|
||||
**Breaking changes:**
|
||||
- Default behavior change: folder CLAUDE.md now disabled by default
|
||||
|
||||
**Action needed:** Resolve conflicts, complete Windows testing.
|
||||
|
||||
---
|
||||
|
||||
## Needs Attention
|
||||
|
||||
### PR #863: Ragtime Email Investigation
|
||||
**Status:** 🔍 Research pending
|
||||
|
||||
Research agent did not return results. Manual review needed.
|
||||
|
||||
---
|
||||
|
||||
### PR #464: Sleep Agent Pipeline (Contributor: @laihenyi)
|
||||
**Status:** 🔴 Too large for effective review
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Additions | 15,430 |
|
||||
| Deletions | 469 |
|
||||
| Files | 73 |
|
||||
| Wait time | 37+ days |
|
||||
| Risk | High |
|
||||
|
||||
**What it does:**
|
||||
- Sleep Agent Pipeline with memory tiering
|
||||
- Supersession detection
|
||||
- Session Statistics API (`/api/session/:id/stats`)
|
||||
- StatusLine + PreCompact hooks
|
||||
- Context Generator improvements
|
||||
- Self-healing CI workflow
|
||||
|
||||
**Concerns:**
|
||||
| Issue | Details |
|
||||
|-------|---------|
|
||||
| 🔴 Size | 15K+ lines is too large for effective review |
|
||||
| 🔴 SupersessionDetector | Single file with 1,282 additions |
|
||||
| 🟡 No tests visible | Test plan checkboxes unchecked |
|
||||
| 🟡 Self-healing CI | Auto-fix workflow could cause infinite commit loops |
|
||||
| 🟡 Serena config | Adds `.serena/` tooling |
|
||||
|
||||
**Recommendation:**
|
||||
1. **Option A:** Request contributor split into 4-5 smaller PRs
|
||||
2. **Option B:** Allocate dedicated review time (several hours)
|
||||
3. **Option C:** Cherry-pick specific features (hooks, stats API)
|
||||
|
||||
**Note:** Contributor has been waiting 37+ days. Deserves response either way.
|
||||
|
||||
---
|
||||
|
||||
## Shipping Strategy
|
||||
|
||||
### Phase 1: Quick Wins (This Week)
|
||||
1. **Merge #856** — Ready now, fixes real user issue
|
||||
2. **Rebase #700** — Has approval, Windows fix needed
|
||||
3. **Rebase #657** — Useful CLI commands
|
||||
|
||||
### Phase 2: Architecture (Careful Review)
|
||||
4. **Review #722** — High impact, conflicts with #700 approach?
|
||||
- Both PRs eliminate spawning but in different ways
|
||||
- May need to pick one approach
|
||||
|
||||
### Phase 3: Contributor PR
|
||||
5. **Respond to #464** — Options:
|
||||
- Ask for split
|
||||
- Schedule dedicated review
|
||||
- Cherry-pick subset
|
||||
|
||||
### Phase 4: Investigation
|
||||
6. **Manual review #863** — Ragtime email feature
|
||||
|
||||
---
|
||||
|
||||
## Conflict Resolution Order
|
||||
|
||||
Since multiple PRs have conflicts, suggested rebase order:
|
||||
|
||||
1. **#856** (merge first — no conflicts)
|
||||
2. **#700** (rebase onto main after #856)
|
||||
3. **#657** (rebase onto main after #700)
|
||||
4. **#722** (rebase last — may conflict with #700 architecturally)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Ready | Conflicts | Needs Work |
|
||||
|-------|-----------|------------|
|
||||
| 1 PR (#856) | 3 PRs (#700, #722, #657) | 2 PRs (#464, #863) |
|
||||
|
||||
**Immediate action:** Merge #856, then rebase the conflict PRs in order.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Version Consistency Fix (Issue #XXX)
|
||||
|
||||
## Problem
|
||||
Version mismatch between plugin and worker caused infinite restart loop:
|
||||
- Plugin version: 9.0.0 (from plugin/.claude-plugin/plugin.json)
|
||||
- Worker binary version: 8.5.9 (hardcoded in bundled worker-service.cjs)
|
||||
|
||||
This triggered the auto-restart mechanism on every hook call, which killed the SDK generator before it could complete the Claude API call to generate observations. Result: 0 observations were ever saved to the database despite hooks firing successfully.
|
||||
|
||||
## Root Cause
|
||||
The `plugin/package.json` file had version `8.5.10` instead of `9.0.0`. When the project was last built, the build script correctly injected the version from root `package.json` into the bundled worker service. However, the `plugin/package.json` was manually created/edited and fell out of sync.
|
||||
|
||||
At runtime:
|
||||
1. Worker service reads version from `~/.claude/plugins/marketplaces/thedotmack/package.json` → gets `8.5.10`
|
||||
2. Running worker returns built-in version via `/api/version` → returns `8.5.9` (from old build)
|
||||
3. Version check in `worker-service.ts` start command detects mismatch
|
||||
4. Auto-restart triggered on every hook call
|
||||
5. Observations never saved
|
||||
|
||||
## Solution
|
||||
1. Updated `plugin/package.json` from version `8.5.10` to `9.0.0`
|
||||
2. Rebuilt all hooks and worker service to inject correct version (`9.0.0`) into bundled artifacts
|
||||
3. Added comprehensive test suite to prevent future version mismatches
|
||||
|
||||
## Verification
|
||||
All versions now match:
|
||||
```
|
||||
Root package.json: 9.0.0 ✓
|
||||
plugin/package.json: 9.0.0 ✓
|
||||
plugin.json: 9.0.0 ✓
|
||||
marketplace.json: 9.0.0 ✓
|
||||
worker-service.cjs: 9.0.0 ✓
|
||||
```
|
||||
|
||||
## Prevention
|
||||
To prevent this issue in the future:
|
||||
|
||||
1. **Automated Build Process**: The `scripts/build-hooks.js` now regenerates `plugin/package.json` automatically with the correct version from root `package.json`
|
||||
|
||||
2. **Version Consistency Tests**: Added `tests/infrastructure/version-consistency.test.ts` to verify all version sources match
|
||||
|
||||
3. **Version Management Best Practices**:
|
||||
- NEVER manually edit `plugin/package.json` - it's auto-generated during build
|
||||
- Always update version in root `package.json` only
|
||||
- Run `npm run build` after version changes
|
||||
- The build script will sync the version to all necessary locations
|
||||
|
||||
## Files Changed
|
||||
- `plugin/package.json` - Updated version from 8.5.10 to 9.0.0
|
||||
- `plugin/scripts/worker-service.cjs` - Rebuilt with version 9.0.0 injected
|
||||
- `plugin/scripts/mcp-server.cjs` - Rebuilt with version 9.0.0 injected
|
||||
- `plugin/scripts/*.js` (hooks) - Rebuilt with version 9.0.0 injected
|
||||
- `tests/infrastructure/version-consistency.test.ts` - New test suite
|
||||
|
||||
## Testing
|
||||
Run the version consistency test:
|
||||
```bash
|
||||
npm run test:infra
|
||||
```
|
||||
|
||||
Or manually verify:
|
||||
```bash
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const rootPkg = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
|
||||
const pluginPkg = JSON.parse(fs.readFileSync('plugin/package.json', 'utf-8'));
|
||||
const workerContent = fs.readFileSync('plugin/scripts/worker-service.cjs', 'utf-8');
|
||||
const workerMatch = workerContent.match(/Bre=\"([0-9.]+)\"/);
|
||||
console.log('Root:', rootPkg.version);
|
||||
console.log('Plugin:', pluginPkg.version);
|
||||
console.log('Worker:', workerMatch ? workerMatch[1] : 'NOT_FOUND');
|
||||
"
|
||||
```
|
||||
|
||||
## Related Code Locations
|
||||
- **Version Injection**: `scripts/build-hooks.js` line 43-45, 105, 130, 155, 178
|
||||
- **Version Check**: `src/services/infrastructure/HealthMonitor.ts` line 133-143
|
||||
- **Auto-Restart Logic**: `src/services/worker-service.ts` line 627-645
|
||||
- **Runtime Version Read**: `src/shared/worker-utils.ts` line 73-76, 82-91
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
Title: Bug: SDK Agent fails on Windows when username contains spaces
|
||||
---
|
||||
|
||||
## Bug Report
|
||||
|
||||
**Summary:** Claude SDK Agent fails to start on Windows when the user's path contains spaces (e.g., `C:\Users\Anderson Wang\`), causing PostToolUse hooks to hang indefinitely.
|
||||
|
||||
**Severity:** High - Core functionality broken
|
||||
|
||||
**Affected Platform:** Windows only
|
||||
|
||||
---
|
||||
|
||||
## Symptoms
|
||||
|
||||
PostToolUse hook displays `(1/2 done)` indefinitely. Worker logs show:
|
||||
|
||||
```
|
||||
ERROR [SESSION] Generator failed {provider=claude, error=Claude Code process exited with code 1}
|
||||
ERROR [SESSION] Generator exited unexpectedly
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Root Cause
|
||||
|
||||
Two issues in the Windows code path:
|
||||
|
||||
1. **`SDKAgent.ts`** - Returns full auto-detected path with spaces:
|
||||
```
|
||||
C:\Users\Anderson Wang\AppData\Roaming\npm\claude.cmd
|
||||
```
|
||||
|
||||
2. **`ProcessRegistry.ts`** - Node.js `spawn()` cannot directly execute `.cmd` files when the path contains spaces
|
||||
|
||||
---
|
||||
|
||||
## Proposed Fix
|
||||
|
||||
### File 1: `src/services/worker/SDKAgent.ts`
|
||||
|
||||
On Windows, prefer `claude.cmd` via PATH instead of full auto-detected path:
|
||||
|
||||
```typescript
|
||||
// On Windows, prefer "claude.cmd" (via PATH) to avoid spawn issues with spaces in paths
|
||||
if (process.platform === 'win32') {
|
||||
try {
|
||||
execSync('where claude.cmd', { encoding: 'utf8', windowsHide: true, stdio: ['ignore', 'pipe', 'ignore'] });
|
||||
return 'claude.cmd'; // Let Windows resolve via PATHEXT
|
||||
} catch {
|
||||
// Fall through to generic error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### File 2: `src/services/worker/ProcessRegistry.ts`
|
||||
|
||||
Use `cmd.exe /d /c` wrapper for .cmd files on Windows:
|
||||
|
||||
```typescript
|
||||
const useCmdWrapper = process.platform === 'win32' && spawnOptions.command.endsWith('.cmd');
|
||||
|
||||
if (useCmdWrapper) {
|
||||
child = spawn('cmd.exe', ['/d', '/c', spawnOptions.command, ...spawnOptions.args], {
|
||||
cwd: spawnOptions.cwd,
|
||||
env: spawnOptions.env,
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
signal: spawnOptions.signal,
|
||||
windowsHide: true
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Why This Works
|
||||
|
||||
- **PATHEXT Resolution:** Windows searches PATH and tries each extension in PATHEXT automatically
|
||||
- **cmd.exe wrapper:** Properly handles paths with spaces and argument passing
|
||||
- **Avoids shell parsing:** Using direct arguments instead of `shell: true` prevents empty string misparsing
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Verified on Windows 11 with username containing spaces:
|
||||
- PostToolUse hook completes successfully
|
||||
- Observations are stored to database
|
||||
- No more "process exited with code 1" errors
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
|
||||
- Maintains backward compatibility with `CLAUDE_CODE_PATH` setting
|
||||
- No impact on non-Windows platforms
|
||||
- Related to Issue #733 (credential isolation) - separate fix
|
||||
@@ -0,0 +1,338 @@
|
||||
# Get started with Claude Code hooks
|
||||
|
||||
> Learn how to customize and extend Claude Code's behavior by registering shell commands
|
||||
|
||||
Claude Code hooks are user-defined shell commands that execute at various points
|
||||
in Claude Code's lifecycle. Hooks provide deterministic control over Claude
|
||||
Code's behavior, ensuring certain actions always happen rather than relying on
|
||||
the LLM to choose to run them.
|
||||
|
||||
<Tip>
|
||||
For reference documentation on hooks, see [Hooks reference](/en/hooks).
|
||||
</Tip>
|
||||
|
||||
Example use cases for hooks include:
|
||||
|
||||
* **Notifications**: Customize how you get notified when Claude Code is awaiting
|
||||
your input or permission to run something.
|
||||
* **Automatic formatting**: Run `prettier` on .ts files, `gofmt` on .go files,
|
||||
etc. after every file edit.
|
||||
* **Logging**: Track and count all executed commands for compliance or
|
||||
debugging.
|
||||
* **Feedback**: Provide automated feedback when Claude Code produces code that
|
||||
does not follow your codebase conventions.
|
||||
* **Custom permissions**: Block modifications to production files or sensitive
|
||||
directories.
|
||||
|
||||
By encoding these rules as hooks rather than prompting instructions, you turn
|
||||
suggestions into app-level code that executes every time it is expected to run.
|
||||
|
||||
<Warning>
|
||||
You must consider the security implication of hooks as you add them, because hooks run automatically during the agent loop with your current environment's credentials.
|
||||
For example, malicious hooks code can exfiltrate your data. Always review your hooks implementation before registering them.
|
||||
|
||||
For full security best practices, see [Security Considerations](/en/hooks#security-considerations) in the hooks reference documentation.
|
||||
</Warning>
|
||||
|
||||
## Hook Events Overview
|
||||
|
||||
Claude Code provides several hook events that run at different points in the
|
||||
workflow:
|
||||
|
||||
* **PreToolUse**: Runs before tool calls (can block them)
|
||||
* **PermissionRequest**: Runs when a permission dialog is shown (can allow or deny)
|
||||
* **PostToolUse**: Runs after tool calls complete
|
||||
* **UserPromptSubmit**: Runs when the user submits a prompt, before Claude processes it
|
||||
* **Notification**: Runs when Claude Code sends notifications
|
||||
* **Stop**: Runs when Claude Code finishes responding
|
||||
* **SubagentStop**: Runs when subagent tasks complete
|
||||
* **PreCompact**: Runs before Claude Code is about to run a compact operation
|
||||
* **SessionStart**: Runs when Claude Code starts a new session or resumes an existing session
|
||||
* **SessionEnd**: Runs when Claude Code session ends
|
||||
|
||||
Each event receives different data and can control Claude's behavior in
|
||||
different ways.
|
||||
|
||||
## Quickstart
|
||||
|
||||
In this quickstart, you'll add a hook that logs the shell commands that Claude
|
||||
Code runs.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install `jq` for JSON processing in the command line.
|
||||
|
||||
### Step 1: Open hooks configuration
|
||||
|
||||
Run the `/hooks` [slash command](/en/slash-commands) and select
|
||||
the `PreToolUse` hook event.
|
||||
|
||||
`PreToolUse` hooks run before tool calls and can block them while providing
|
||||
Claude feedback on what to do differently.
|
||||
|
||||
### Step 2: Add a matcher
|
||||
|
||||
Select `+ Add new matcher…` to run your hook only on Bash tool calls.
|
||||
|
||||
Type `Bash` for the matcher.
|
||||
|
||||
<Note>You can use `*` to match all tools.</Note>
|
||||
|
||||
### Step 3: Add the hook
|
||||
|
||||
Select `+ Add new hook…` and enter this command:
|
||||
|
||||
```bash theme={null}
|
||||
jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt
|
||||
```
|
||||
|
||||
### Step 4: Save your configuration
|
||||
|
||||
For storage location, select `User settings` since you're logging to your home
|
||||
directory. This hook will then apply to all projects, not just your current
|
||||
project.
|
||||
|
||||
Then press `Esc` until you return to the REPL. Your hook is now registered.
|
||||
|
||||
### Step 5: Verify your hook
|
||||
|
||||
Run `/hooks` again or check `~/.claude/settings.json` to see your configuration:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "jq -r '\"\\(.tool_input.command) - \\(.tool_input.description // \"No description\")\"' >> ~/.claude/bash-command-log.txt"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Test your hook
|
||||
|
||||
Ask Claude to run a simple command like `ls` and check your log file:
|
||||
|
||||
```bash theme={null}
|
||||
cat ~/.claude/bash-command-log.txt
|
||||
```
|
||||
|
||||
You should see entries like:
|
||||
|
||||
```
|
||||
ls - Lists files and directories
|
||||
```
|
||||
|
||||
## More Examples
|
||||
|
||||
<Note>
|
||||
For a complete example implementation, see the [bash command validator example](https://github.com/anthropics/claude-code/blob/main/examples/hooks/bash_command_validator_example.py) in our public codebase.
|
||||
</Note>
|
||||
|
||||
### Code Formatting Hook
|
||||
|
||||
Automatically format TypeScript files after editing:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.ts$'; then npx prettier --write \"$file_path\"; fi; }"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Markdown Formatting Hook
|
||||
|
||||
Automatically fix missing language tags and formatting issues in markdown files:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/markdown_formatter.py"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Create `.claude/hooks/markdown_formatter.py` with this content:
|
||||
|
||||
````python theme={null}
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Markdown formatter for Claude Code output.
|
||||
Fixes missing language tags and spacing issues while preserving code content.
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
def detect_language(code):
|
||||
"""Best-effort language detection from code content."""
|
||||
s = code.strip()
|
||||
|
||||
# JSON detection
|
||||
if re.search(r'^\s*[{\[]', s):
|
||||
try:
|
||||
json.loads(s)
|
||||
return 'json'
|
||||
except:
|
||||
pass
|
||||
|
||||
# Python detection
|
||||
if re.search(r'^\s*def\s+\w+\s*\(', s, re.M) or \
|
||||
re.search(r'^\s*(import|from)\s+\w+', s, re.M):
|
||||
return 'python'
|
||||
|
||||
# JavaScript detection
|
||||
if re.search(r'\b(function\s+\w+\s*\(|const\s+\w+\s*=)', s) or \
|
||||
re.search(r'=>|console\.(log|error)', s):
|
||||
return 'javascript'
|
||||
|
||||
# Bash detection
|
||||
if re.search(r'^#!.*\b(bash|sh)\b', s, re.M) or \
|
||||
re.search(r'\b(if|then|fi|for|in|do|done)\b', s):
|
||||
return 'bash'
|
||||
|
||||
# SQL detection
|
||||
if re.search(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE)\s+', s, re.I):
|
||||
return 'sql'
|
||||
|
||||
return 'text'
|
||||
|
||||
def format_markdown(content):
|
||||
"""Format markdown content with language detection."""
|
||||
# Fix unlabeled code fences
|
||||
def add_lang_to_fence(match):
|
||||
indent, info, body, closing = match.groups()
|
||||
if not info.strip():
|
||||
lang = detect_language(body)
|
||||
return f"{indent}```{lang}\n{body}{closing}\n"
|
||||
return match.group(0)
|
||||
|
||||
fence_pattern = r'(?ms)^([ \t]{0,3})```([^\n]*)\n(.*?)(\n\1```)\s*$'
|
||||
content = re.sub(fence_pattern, add_lang_to_fence, content)
|
||||
|
||||
# Fix excessive blank lines (only outside code fences)
|
||||
content = re.sub(r'\n{3,}', '\n\n', content)
|
||||
|
||||
return content.rstrip() + '\n'
|
||||
|
||||
# Main execution
|
||||
try:
|
||||
input_data = json.load(sys.stdin)
|
||||
file_path = input_data.get('tool_input', {}).get('file_path', '')
|
||||
|
||||
if not file_path.endswith(('.md', '.mdx')):
|
||||
sys.exit(0) # Not a markdown file
|
||||
|
||||
if os.path.exists(file_path):
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
formatted = format_markdown(content)
|
||||
|
||||
if formatted != content:
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.write(formatted)
|
||||
print(f"✓ Fixed markdown formatting in {file_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error formatting markdown: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
````
|
||||
|
||||
Make the script executable:
|
||||
|
||||
```bash theme={null}
|
||||
chmod +x .claude/hooks/markdown_formatter.py
|
||||
```
|
||||
|
||||
This hook automatically:
|
||||
|
||||
* Detects programming languages in unlabeled code blocks
|
||||
* Adds appropriate language tags for syntax highlighting
|
||||
* Fixes excessive blank lines while preserving code content
|
||||
* Only processes markdown files (`.md`, `.mdx`)
|
||||
|
||||
### Custom Notification Hook
|
||||
|
||||
Get desktop notifications when Claude needs input:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"hooks": {
|
||||
"Notification": [
|
||||
{
|
||||
"matcher": "",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "notify-send 'Claude Code' 'Awaiting your input'"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### File Protection Hook
|
||||
|
||||
Block edits to sensitive files:
|
||||
|
||||
```json theme={null}
|
||||
{
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Edit|Write",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 -c \"import json, sys; data=json.load(sys.stdin); path=data.get('tool_input',{}).get('file_path',''); sys.exit(2 if any(p in path for p in ['.env', 'package-lock.json', '.git/']) else 0)\""
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Learn more
|
||||
|
||||
* For reference documentation on hooks, see [Hooks reference](/en/hooks).
|
||||
* For comprehensive security best practices and safety guidelines, see [Security Considerations](/en/hooks#security-considerations) in the hooks reference documentation.
|
||||
* For troubleshooting steps and debugging techniques, see [Debugging](/en/hooks#debugging) in the hooks reference
|
||||
documentation.
|
||||
|
||||
|
||||
---
|
||||
|
||||
> To find navigation and other pages in this documentation, fetch the llms.txt file at: https://code.claude.com/docs/llms.txt
|
||||
+55
-47
@@ -1,5 +1,4 @@
|
||||
🌐 هذه ترجمة آلية. نرحب بالتصحيحات من المجتمع!
|
||||
|
||||
<section dir="rtl">
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
@@ -14,6 +13,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +33,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -43,7 +44,8 @@
|
||||
<a href="README.no.md">🇳🇴 Norsk</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">نظام ضغط الذاكرة المستمرة المبني لـ <a href="https://claude.com/claude-code" target="_blank">Claude Code</a>.</h4>
|
||||
<h4 align="center">أداة إضافية لـ <a href="https://claude.com/claude-code" target="_blank">Claude Code</a> تعمل على أتمتة تسجيل معلومات الجلسات السابقه، وضغطها, ثم حقن السياق ذي الصلة في الجلسات المستقبلية.
|
||||
</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
@@ -80,25 +82,27 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#البدء-السريع">البدء السريع</a> •
|
||||
<a href="#كيف-يعمل">كيف يعمل</a> •
|
||||
<a href="#أدوات-البحث-mcp">أدوات البحث</a> •
|
||||
<a href="#التوثيق">التوثيق</a> •
|
||||
<a href="#الإعدادات">الإعدادات</a> •
|
||||
<a href="#استكشاف-الأخطاء-وإصلاحها">استكشاف الأخطاء وإصلاحها</a> •
|
||||
<a href="#الترخيص">الترخيص</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
يحافظ Claude-Mem بسلاسة على السياق عبر الجلسات من خلال التقاط الملاحظات حول استخدام الأدوات تلقائيًا، وإنشاء ملخصات دلالية، وإتاحتها للجلسات المستقبلية. هذا يمكّن Claude من الحفاظ على استمرارية المعرفة حول المشاريع حتى بعد انتهاء الجلسات أو إعادة الاتصال.
|
||||
<a href="#بداية-سريعة">بداية سريعة</a> •
|
||||
<a href="#كيف-يعمل">كيف يعمل</a> •
|
||||
<a href="#أدوات-البحث-mcp-search-tools">أدوات البحث</a> •
|
||||
<a href="#المستندات">التوثيق</a> •
|
||||
<a href="#الإعدادات">الإعدادات</a> •
|
||||
<a href="#استكشاف-الأخطاء-وإصلاحها">استكشاف الأخطاء وإصلاحها</a> •
|
||||
<a href="#الترخيص-license">الترخيص</a>
|
||||
</p>
|
||||
|
||||
<p align="center" dir="rtl">
|
||||
Claude-Mem هو نظام متطور مصمم لضغط وحفظ الذاكرة لسياق عمل Claude Code. وظيفته الأساسية هي جعل "كلود" يتذكر ما فعله في جلسات العمل السابقة بسلاسة، عبر تسجيل تحركاته، وإنشاء ملخصات ذكية، واستدعائها في الجلسات المستقبلية. هذا يضمن عدم ضياع سياق المشروع حتى لو أغلقت البرنامج وفتحته لاحقاً.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## البدء السريع
|
||||
## بداية سريعة
|
||||
|
||||
ابدأ جلسة Claude Code جديدة في الطرفية وأدخل الأوامر التالية:
|
||||
للبدء، افتح "Claude Code" في مبنى الأوامر (Terminal) واكتب الأوامر التالية:
|
||||
<div dir="ltr" align="left">
|
||||
|
||||
```
|
||||
> /plugin marketplace add thedotmack/claude-mem
|
||||
@@ -106,32 +110,34 @@
|
||||
> /plugin install claude-mem
|
||||
```
|
||||
|
||||
أعد تشغيل Claude Code. سيظهر السياق من الجلسات السابقة تلقائيًا في الجلسات الجديدة.
|
||||
</div>
|
||||
|
||||
بمجرد إعادة تشغيل Claude Code، سيتم استدعاء السياق من الجلسات السابقة تلقائيا عند الحاجة.
|
||||
|
||||
**الميزات الرئيسية:**
|
||||
|
||||
- 🧠 **ذاكرة مستمرة** - يبقى السياق عبر الجلسات
|
||||
- 📊 **الكشف التدريجي** - استرجاع الذاكرة بطبقات مع رؤية تكلفة الرموز
|
||||
- 🔍 **بحث قائم على المهارات** - استعلم عن تاريخ مشروعك باستخدام مهارة mem-search
|
||||
- 🖥️ **واجهة مستخدم ويب** - بث الذاكرة المباشر على http://localhost:37777
|
||||
- 💻 **مهارة Claude Desktop** - ابحث في الذاكرة من محادثات Claude Desktop
|
||||
- 🔒 **التحكم في الخصوصية** - استخدم وسوم `<private>` لاستبعاد المحتوى الحساس من التخزين
|
||||
- ⚙️ **إعدادات السياق** - تحكم دقيق في السياق الذي يتم حقنه
|
||||
- 🤖 **تشغيل تلقائي** - لا يتطلب تدخلاً يدويًا
|
||||
- 🔗 **الاستشهادات** - رجوع إلى الملاحظات السابقة باستخدام المعرفات (الوصول عبر http://localhost:37777/api/observation/{id} أو عرض الكل في عارض الويب على http://localhost:37777)
|
||||
- 🧪 **قناة تجريبية** - جرّب الميزات التجريبية مثل Endless Mode عبر تبديل الإصدار
|
||||
- 🧠 **ذاكرة مستديمه**: سياق عملك لا ينتهي بانتهاء الجلسة، بل ينتقل معك للجلسة التالية.
|
||||
- 📊 **الكشف التدريجي** (Progressive Disclosure): نظام ذكي يستدعي المعلومات على طبقات، مما يمنحك رؤية واضحة لاستهلاك الـ "Tokens" (التكلفة).
|
||||
- 🔍 **بحث سريع** - استعلم عن سجل مشروعك باستخدام خاصية `mem-search`.
|
||||
- 🖥️ **واجهة مستخدم ويب** - رؤية معلومات الذاكرة مع تحديث فوري عبر المتصفح من خلال الرابط: http://localhost:37777
|
||||
- 💻 **تكامل مع Claude Desktop** - إمكانية البحث في الذاكرة مباشرة من واجهة Claude المكتبية
|
||||
- 🔒 **التحكم في الخصوصية** - دعم وسم `<private>` لمنع النظام من تخزين أي معلومات حساسة.
|
||||
- ⚙️ **إعدادات السياق** - تحكم دقيق في السياق (context) التي سيتم حقنها في سياق المحادثة.
|
||||
- 🤖 **أتمتة كاملة:** - النظام يعمل في الخلفية دون الحاجة لتدخل يدوي منك.
|
||||
- 🔗 **الاستشهادات** - رجوع إلى الملاحظات السابقة باستخدام (http://localhost:37777/api/observation/{id} أو عرض جميع المعلومات على http://localhost:37777)
|
||||
- 🧪 **مزايا التجريبيه** - تجربة مميزات مثل "الوضع اللانهائي" (Endless Mode).
|
||||
|
||||
---
|
||||
|
||||
## التوثيق
|
||||
## المستندات
|
||||
|
||||
📚 **[عرض التوثيق الكامل](docs/)** - تصفح مستندات markdown على GitHub
|
||||
📚 **[عرض التوثيق الكامل](https://docs.claude-mem.ai/)** - تصفح على الموقع الرسمي
|
||||
|
||||
### البدء
|
||||
|
||||
- **[دليل التثبيت](https://docs.claude-mem.ai/installation)** - البدء السريع والتثبيت المتقدم
|
||||
- **[دليل الاستخدام](https://docs.claude-mem.ai/usage/getting-started)** - كيف يعمل Claude-Mem تلقائيًا
|
||||
- **[أدوات البحث](https://docs.claude-mem.ai/usage/search-tools)** - استعلم عن تاريخ مشروعك باللغة الطبيعية
|
||||
- **[أدوات البحث](https://docs.claude-mem.ai/usage/search-tools)** - استعلم عن سجل مشروعك بلغتك
|
||||
- **[الميزات التجريبية](https://docs.claude-mem.ai/beta-features)** - جرّب الميزات التجريبية مثل Endless Mode
|
||||
|
||||
### أفضل الممارسات
|
||||
@@ -142,9 +148,9 @@
|
||||
### البنية المعمارية
|
||||
|
||||
- **[نظرة عامة](https://docs.claude-mem.ai/architecture/overview)** - مكونات النظام وتدفق البيانات
|
||||
- **[تطور البنية المعمارية](https://docs.claude-mem.ai/architecture-evolution)** - الرحلة من v3 إلى v5
|
||||
- **[بنية الخطافات](https://docs.claude-mem.ai/hooks-architecture)** - كيف يستخدم Claude-Mem خطافات دورة الحياة
|
||||
- **[مرجع الخطافات](https://docs.claude-mem.ai/architecture/hooks)** - شرح 7 سكريبتات خطافات
|
||||
- **[تطور البنية المعمارية](https://docs.claude-mem.ai/architecture-evolution)** - تطور المعمارية من v3 إلى v5
|
||||
- **[بنية برامج الربط (Hooks)](https://docs.claude-mem.ai/hooks-architecture)** - كيف يستخدم Claude-Mem خطافات دورة الحياة
|
||||
- **[مرجع برامج الربط (Hooks)](https://docs.claude-mem.ai/architecture/hooks)** - شرح 7 سكريبتات خطافات
|
||||
- **[خدمة العامل](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API وإدارة Bun
|
||||
- **[قاعدة البيانات](https://docs.claude-mem.ai/architecture/database)** - مخطط SQLite وبحث FTS5
|
||||
- **[بنية البحث](https://docs.claude-mem.ai/architecture/search-architecture)** - البحث المختلط مع قاعدة بيانات المتجهات Chroma
|
||||
@@ -161,24 +167,23 @@
|
||||
|
||||
**المكونات الأساسية:**
|
||||
|
||||
1. **5 خطافات دورة الحياة** - SessionStart، UserPromptSubmit، PostToolUse، Stop، SessionEnd (6 سكريبتات خطافات)
|
||||
2. **تثبيت ذكي** - فاحص التبعيات المخزنة مؤقتًا (سكريبت ما قبل الخطاف، ليس خطاف دورة حياة)
|
||||
1. **5 برامج ربط (Hooks)** - SessionStart، UserPromptSubmit، PostToolUse، Stop، SessionEnd
|
||||
2. **تثبيت ذكي** - فاحص التبعيات المخزنة مؤقتًا
|
||||
3. **خدمة العامل** - HTTP API على المنفذ 37777 مع واجهة مستخدم عارض الويب و10 نقاط نهاية للبحث، تديرها Bun
|
||||
4. **قاعدة بيانات SQLite** - تخزن الجلسات، الملاحظات، الملخصات
|
||||
5. **مهارة mem-search** - استعلامات اللغة الطبيعية مع الكشف التدريجي
|
||||
6. **قاعدة بيانات المتجهات Chroma** - البحث المختلط الدلالي + الكلمات المفتاحية لاسترجاع السياق الذكي
|
||||
6. **قاعدة بيانات المتجهات Chroma** - البحث الدلالي الهجين + الكلمات المفتاحية لاسترجاع السياق الذكي
|
||||
|
||||
انظر [نظرة عامة على البنية المعمارية](https://docs.claude-mem.ai/architecture/overview) للتفاصيل.
|
||||
|
||||
---
|
||||
|
||||
## مهارة mem-search
|
||||
|
||||
## أدوات البحث (MCP Search Tools)
|
||||
يوفر Claude-Mem بحثًا ذكيًا من خلال مهارة mem-search التي تُستدعى تلقائيًا عندما تسأل عن العمل السابق:
|
||||
|
||||
**كيف يعمل:**
|
||||
- فقط اسأل بشكل طبيعي: *"ماذا فعلنا في الجلسة الأخيرة؟"* أو *"هل أصلحنا هذا الخطأ من قبل؟"*
|
||||
- يستدعي Claude تلقائيًا مهارة mem-search للعثور على السياق ذي الصلة
|
||||
- يستدعي Claude تلقائيًا خاصية mem-search للعثور على السياق ذي الصلة
|
||||
|
||||
**عمليات البحث المتاحة:**
|
||||
|
||||
@@ -193,7 +198,7 @@
|
||||
9. **الجدول الزمني حسب الاستعلام** - البحث عن الملاحظات والحصول على سياق الجدول الزمني حول أفضل تطابق
|
||||
10. **مساعدة API** - الحصول على توثيق API البحث
|
||||
|
||||
**أمثلة على استعلامات اللغة الطبيعية:**
|
||||
**أمثلة على الاستعلامات:**
|
||||
|
||||
```
|
||||
"What bugs did we fix last session?"
|
||||
@@ -219,8 +224,7 @@
|
||||
|
||||
- **Node.js**: 18.0.0 أو أعلى
|
||||
- **Claude Code**: أحدث إصدار مع دعم الإضافات
|
||||
- **Bun**: بيئة تشغيل JavaScript ومدير العمليات (يُثبت تلقائيًا إذا كان مفقودًا)
|
||||
- **uv**: مدير حزم Python للبحث المتجهي (يُثبت تلقائيًا إذا كان مفقودًا)
|
||||
- **Bun & uv**: (يتم تثبيتهما تلقائياً) لإدارة العمليات والبحث المتجه.
|
||||
- **SQLite 3**: للتخزين المستمر (مدمج)
|
||||
|
||||
---
|
||||
@@ -241,7 +245,7 @@
|
||||
|
||||
## استكشاف الأخطاء وإصلاحها
|
||||
|
||||
إذا واجهت مشكلات، صِف المشكلة لـ Claude وستقوم مهارة troubleshoot تلقائيًا بتشخيصها وتوفير الإصلاحات.
|
||||
إذا واجهت مشكلة، اشرحها لـ Claude وسيقوم بتشغيل خاصية troubleshoot لإصلاحها ذاتياً.
|
||||
|
||||
انظر **[دليل استكشاف الأخطاء وإصلاحها](https://docs.claude-mem.ai/troubleshooting)** للمشكلات الشائعة والحلول.
|
||||
|
||||
@@ -250,27 +254,29 @@
|
||||
## تقارير الأخطاء
|
||||
|
||||
أنشئ تقارير أخطاء شاملة باستخدام المولّد الآلي:
|
||||
<div align=left>
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
npm run bug-report
|
||||
```
|
||||
</div>
|
||||
|
||||
## المساهمة
|
||||
|
||||
المساهمات مرحب بها! يُرجى:
|
||||
|
||||
1. عمل Fork للمستودع
|
||||
2. إنشاء فرع ميزة
|
||||
1. عمل Fork للمشروع (Repository)
|
||||
2. إنشاء فرع (branch)
|
||||
3. إجراء التغييرات مع الاختبارات
|
||||
4. تحديث التوثيق
|
||||
4. تحديث المستندات عند الحاجه
|
||||
5. تقديم Pull Request
|
||||
|
||||
انظر [دليل التطوير](https://docs.claude-mem.ai/development) لسير عمل المساهمة.
|
||||
|
||||
---
|
||||
|
||||
## الترخيص
|
||||
## الترخيص (License)
|
||||
|
||||
هذا المشروع مرخص بموجب **ترخيص GNU Affero العام الإصدار 3.0** (AGPL-3.0).
|
||||
|
||||
@@ -298,4 +304,6 @@ npm run bug-report
|
||||
|
||||
---
|
||||
|
||||
**مبني باستخدام Claude Agent SDK** | **مدعوم بواسطة Claude Code** | **صُنع باستخدام TypeScript**
|
||||
**مبني باستخدام Claude Agent SDK** | **مدعوم بواسطة Claude Code** | **صُنع باستخدام TypeScript**
|
||||
|
||||
</section>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Claude Code পুনরায় চালু করুন। পূর্ব
|
||||
|
||||
## ডকুমেন্টেশন
|
||||
|
||||
📚 **[সম্পূর্ণ ডকুমেন্টেশন দেখুন](docs/)** - GitHub-এ markdown ডক্স ব্রাউজ করুন
|
||||
📚 **[সম্পূর্ণ ডকুমেন্টেশন দেখুন](https://docs.claude-mem.ai/)** - অফিসিয়াল ওয়েবসাইটে ব্রাউজ করুন
|
||||
|
||||
### শুরু করা
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Restartujte Claude Code. Kontext z předchozích sezení se automaticky objeví
|
||||
|
||||
## Dokumentace
|
||||
|
||||
📚 **[Zobrazit kompletní dokumentaci](docs/)** - Procházejte dokumentaci v markdown na GitHubu
|
||||
📚 **[Zobrazit kompletní dokumentaci](https://docs.claude-mem.ai/)** - Procházet na oficiálních stránkách
|
||||
|
||||
### Začínáme
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Genstart Claude Code. Kontekst fra tidligere sessioner vil automatisk vises i ny
|
||||
|
||||
## Dokumentation
|
||||
|
||||
📚 **[Se Fuld Dokumentation](docs/)** - Gennemse markdown-dokumenter på GitHub
|
||||
📚 **[Se Fuld Dokumentation](https://docs.claude-mem.ai/)** - Gennemse på den officielle hjemmeside
|
||||
|
||||
### Kom Godt I Gang
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Starten Sie Claude Code neu. Kontext aus vorherigen Sitzungen wird automatisch i
|
||||
|
||||
## Dokumentation
|
||||
|
||||
📚 **[Vollständige Dokumentation anzeigen](docs/)** - Markdown-Dokumentation auf GitHub durchsuchen
|
||||
📚 **[Vollständige Dokumentation anzeigen](https://docs.claude-mem.ai/)** - Auf der offiziellen Website durchsuchen
|
||||
|
||||
### Erste Schritte
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
## Τεκμηρίωση
|
||||
|
||||
📚 **[Προβολή Πλήρους Τεκμηρίωσης](docs/)** - Περιήγηση στα markdown έγγραφα στο GitHub
|
||||
📚 **[Προβολή Πλήρους Τεκμηρίωσης](https://docs.claude-mem.ai/)** - Περιήγηση στον επίσημο ιστότοπο
|
||||
|
||||
### Ξεκινώντας
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -35,6 +36,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -127,7 +129,7 @@ Reinicia Claude Code. El contexto de sesiones anteriores aparecerá automáticam
|
||||
|
||||
## Documentación
|
||||
|
||||
📚 **[Ver Documentación Completa](docs/)** - Explora documentos markdown en GitHub
|
||||
📚 **[Ver Documentación Completa](https://docs.claude-mem.ai/)** - Navegar en el sitio web oficial
|
||||
|
||||
### Primeros Pasos
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@ Käynnistä Claude Code uudelleen. Aiempien istuntojen konteksti ilmestyy automa
|
||||
|
||||
## Dokumentaatio
|
||||
|
||||
📚 **[Näytä täydellinen dokumentaatio](docs/)** - Selaa markdown-dokumentteja GitHubissa
|
||||
📚 **[Näytä täydellinen dokumentaatio](https://docs.claude-mem.ai/)** - Selaa virallisella verkkosivustolla
|
||||
|
||||
### Aloitus
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Redémarrez Claude Code. Le contexte des sessions précédentes apparaîtra auto
|
||||
|
||||
## Documentation
|
||||
|
||||
📚 **[Voir la documentation complète](docs/)** - Parcourez la documentation markdown sur GitHub
|
||||
📚 **[Voir la documentation complète](https://docs.claude-mem.ai/)** - Parcourir sur le site officiel
|
||||
|
||||
### Pour commencer
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@
|
||||
|
||||
## תיעוד
|
||||
|
||||
📚 **[צפה בתיעוד המלא](docs/)** - עיין במסמכי markdown ב-GitHub
|
||||
📚 **[צפה בתיעוד המלא](https://docs.claude-mem.ai/)** - דפדף באתר הרשמי
|
||||
|
||||
### תחילת העבודה
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Claude Code को पुनः आरंभ करें। पिछले स
|
||||
|
||||
## दस्तावेज़ीकरण
|
||||
|
||||
📚 **[पूर्ण दस्तावेज़ीकरण देखें](docs/)** - GitHub पर markdown दस्तावेज़ ब्राउज़ करें
|
||||
📚 **[पूर्ण दस्तावेज़ीकरण देखें](https://docs.claude-mem.ai/)** - आधिकारिक वेबसाइट पर ब्राउज़ करें
|
||||
|
||||
### शुरुआत करना
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Indítsa újra a Claude Code-ot. A korábbi munkamenetek kontextusa automatikusa
|
||||
|
||||
## Dokumentáció
|
||||
|
||||
📚 **[Teljes dokumentáció megtekintése](docs/)** - Markdown dokumentumok böngészése GitHub-on
|
||||
📚 **[Teljes dokumentáció megtekintése](https://docs.claude-mem.ai/)** - Böngészés a hivatalos weboldalon
|
||||
|
||||
### Első lépések
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Restart Claude Code. Konteks dari sesi sebelumnya akan secara otomatis muncul di
|
||||
|
||||
## Dokumentasi
|
||||
|
||||
📚 **[Lihat Dokumentasi Lengkap](docs/)** - Telusuri dokumen markdown di GitHub
|
||||
📚 **[Lihat Dokumentasi Lengkap](https://docs.claude-mem.ai/)** - Jelajahi di situs web resmi
|
||||
|
||||
### Memulai
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Riavvia Claude Code. Il contesto delle sessioni precedenti apparirà automaticam
|
||||
|
||||
## Documentazione
|
||||
|
||||
📚 **[Visualizza Documentazione Completa](docs/)** - Sfoglia i documenti markdown su GitHub
|
||||
📚 **[Visualizza Documentazione Completa](https://docs.claude-mem.ai/)** - Sfoglia sul sito ufficiale
|
||||
|
||||
### Per Iniziare
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Claude Codeを再起動します。以前のセッションからのコンテキ
|
||||
|
||||
## ドキュメント
|
||||
|
||||
📚 **[完全なドキュメントを見る](docs/)** - GitHubでマークダウンドキュメントを閲覧
|
||||
📚 **[完全なドキュメントを見る](https://docs.claude-mem.ai/)** - 公式ウェブサイトで閲覧
|
||||
|
||||
### はじめに
|
||||
|
||||
@@ -212,7 +214,7 @@ Claude-Memは、過去の作業について尋ねると自動的に呼び出さ
|
||||
|
||||
Claude-Memは、**Endless Mode**(拡張セッション用の生体模倣メモリアーキテクチャ)などの実験的機能を備えた**ベータチャネル**を提供します。http://localhost:37777 → SettingsのWebビューアUIから安定版とベータ版を切り替えます。
|
||||
|
||||
Endless Modeと試用方法の詳細については、**[ベータ機能ドキュメント](https://docs.claude-mem.ai/beta-features)**を参照してください。
|
||||
Endless Modeと試用方法の詳細については、**[ベータ機能ドキュメント](https://docs.claude-mem.ai/beta-features)** を参照してください。
|
||||
|
||||
---
|
||||
|
||||
@@ -230,13 +232,13 @@ Endless Modeと試用方法の詳細については、**[ベータ機能ドキ
|
||||
|
||||
設定は`~/.claude-mem/settings.json`で管理されます(初回実行時にデフォルト値で自動作成)。AIモデル、ワーカーポート、データディレクトリ、ログレベル、コンテキスト注入設定を構成します。
|
||||
|
||||
利用可能なすべての設定と例については、**[設定ガイド](https://docs.claude-mem.ai/configuration)**を参照してください。
|
||||
利用可能なすべての設定と例については、**[設定ガイド](https://docs.claude-mem.ai/configuration)** を参照してください。
|
||||
|
||||
---
|
||||
|
||||
## 開発
|
||||
|
||||
ビルド手順、テスト、コントリビューションワークフローについては、**[開発ガイド](https://docs.claude-mem.ai/development)**を参照してください。
|
||||
ビルド手順、テスト、コントリビューションワークフローについては、**[開発ガイド](https://docs.claude-mem.ai/development)** を参照してください。
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +246,7 @@ Endless Modeと試用方法の詳細については、**[ベータ機能ドキ
|
||||
|
||||
問題が発生した場合は、Claudeに問題を説明すると、troubleshootスキルが自動的に診断して修正を提供します。
|
||||
|
||||
よくある問題と解決策については、**[トラブルシューティングガイド](https://docs.claude-mem.ai/troubleshooting)**を参照してください。
|
||||
よくある問題と解決策については、**[トラブルシューティングガイド](https://docs.claude-mem.ai/troubleshooting)** を参照してください。
|
||||
|
||||
---
|
||||
|
||||
@@ -286,7 +288,7 @@ Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
|
||||
- 派生作品もAGPL-3.0の下でライセンスする必要があります
|
||||
- このソフトウェアには保証がありません
|
||||
|
||||
**Ragtimeに関する注意**: `ragtime/`ディレクトリは**PolyForm Noncommercial License 1.0.0**の下で個別にライセンスされています。詳細は[ragtime/LICENSE](ragtime/LICENSE)を参照してください。
|
||||
**Ragtimeに関する注意**: `ragtime/`ディレクトリは **PolyForm Noncommercial License 1.0.0** の下で個別にライセンスされています。詳細は[ragtime/LICENSE](ragtime/LICENSE)を参照してください。
|
||||
|
||||
---
|
||||
|
||||
@@ -299,4 +301,4 @@ Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
|
||||
|
||||
---
|
||||
|
||||
**Claude Agent SDKで構築** | **Claude Codeで動作** | **TypeScriptで作成**
|
||||
**Claude Agent SDKで構築** | **Claude Codeで動作** | **TypeScriptで作成**
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -114,19 +116,19 @@ Claude Code를 재시작하세요. 이전 세션의 컨텍스트가 자동으로
|
||||
- 🧠 **지속적인 메모리** - 세션 간 컨텍스트 유지
|
||||
- 📊 **점진적 공개** - 토큰 비용 가시성을 갖춘 계층화된 메모리 검색
|
||||
- 🔍 **스킬 기반 검색** - mem-search 스킬로 프로젝트 기록 쿼리
|
||||
- 🖥️ **웹 뷰어 UI** - http://localhost:37777에서 실시간 메모리 스트림 확인
|
||||
- 🖥️ **웹 뷰어 UI** - http://localhost:37777 에서 실시간 메모리 스트림 확인
|
||||
- 💻 **Claude Desktop 스킬** - Claude Desktop 대화에서 메모리 검색
|
||||
- 🔒 **개인정보 제어** - `<private>` 태그를 사용하여 민감한 콘텐츠를 저장소에서 제외
|
||||
- ⚙️ **컨텍스트 설정** - 주입되는 컨텍스트에 대한 세밀한 제어
|
||||
- 🤖 **자동 작동** - 수동 개입 불필요
|
||||
- 🔗 **인용** - ID로 과거 관찰 참조 (http://localhost:37777/api/observation/{id}를 통해 액세스하거나 http://localhost:37777의 웹 뷰어에서 모두 보기)
|
||||
- 🔗 **인용** - ID로 과거 관찰 참조 (http://localhost:37777/api/observation/{id} 를 통해 액세스하거나 http://localhost:37777 의 웹 뷰어에서 모두 보기)
|
||||
- 🧪 **베타 채널** - 버전 전환을 통해 Endless Mode와 같은 실험적 기능 사용
|
||||
|
||||
---
|
||||
|
||||
## 문서
|
||||
|
||||
📚 **[전체 문서 보기](docs/)** - GitHub에서 마크다운 문서 탐색
|
||||
📚 **[전체 문서 보기](https://docs.claude-mem.ai/)** - 공식 웹사이트에서 찾아보기
|
||||
|
||||
### 시작하기
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@ Herstart Claude Code. Context van eerdere sessies verschijnt automatisch in nieu
|
||||
|
||||
## Documentatie
|
||||
|
||||
📚 **[Bekijk Volledige Documentatie](docs/)** - Blader door markdown documenten op GitHub
|
||||
📚 **[Bekijk Volledige Documentatie](https://docs.claude-mem.ai/)** - Bladeren op de officiële website
|
||||
|
||||
### Aan de Slag
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Start Claude Code på nytt. Kontekst fra tidligere økter vil automatisk vises i
|
||||
|
||||
## Dokumentasjon
|
||||
|
||||
📚 **[Se Full Dokumentasjon](docs/)** - Bla gjennom markdown-dokumenter på GitHub
|
||||
📚 **[Se Full Dokumentasjon](https://docs.claude-mem.ai/)** - Bla gjennom på det offisielle nettstedet
|
||||
|
||||
### Komme I Gang
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@ Uruchom ponownie Claude Code. Kontekst z poprzednich sesji automatycznie pojawi
|
||||
|
||||
## Dokumentacja
|
||||
|
||||
📚 **[Wyświetl Pełną Dokumentację](docs/)** - Przeglądaj dokumentację markdown na GitHub
|
||||
📚 **[Wyświetl Pełną Dokumentację](https://docs.claude-mem.ai/)** - Przeglądaj na oficjalnej stronie
|
||||
|
||||
### Pierwsze Kroki
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Reinicie o Claude Code. O contexto de sessões anteriores aparecerá automaticam
|
||||
|
||||
## Documentação
|
||||
|
||||
📚 **[Ver Documentação Completa](docs/)** - Navegue pelos documentos markdown no GitHub
|
||||
📚 **[Ver Documentação Completa](https://docs.claude-mem.ai/)** - Navegar no site oficial
|
||||
|
||||
### Começando
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Reporniți Claude Code. Contextul din sesiunile anterioare va apărea automat î
|
||||
|
||||
## Documentație
|
||||
|
||||
📚 **[Vizualizați Documentația Completă](docs/)** - Răsfoiți documentele markdown pe GitHub
|
||||
📚 **[Vizualizați Documentația Completă](https://docs.claude-mem.ai/)** - Răsfoiți pe site-ul oficial
|
||||
|
||||
### Introducere
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
## Документация
|
||||
|
||||
📚 **[Просмотреть полную документацию](docs/)** - Просмотр markdown-документов на GitHub
|
||||
📚 **[Просмотреть полную документацию](https://docs.claude-mem.ai/)** - Просмотр на официальном сайте
|
||||
|
||||
### Начало работы
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Starta om Claude Code. Kontext från tidigare sessioner kommer automatiskt att v
|
||||
|
||||
## Dokumentation
|
||||
|
||||
📚 **[Visa fullständig dokumentation](docs/)** - Bläddra bland markdown-dokument på GitHub
|
||||
📚 **[Visa fullständig dokumentation](https://docs.claude-mem.ai/)** - Bläddra på den officiella webbplatsen
|
||||
|
||||
### Komma igång
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@
|
||||
|
||||
## เอกสาร
|
||||
|
||||
📚 **[ดูเอกสารฉบับเต็ม](docs/)** - เรียกดูเอกสาร markdown บน GitHub
|
||||
📚 **[ดูเอกสารฉบับเต็ม](https://docs.claude-mem.ai/)** - เรียกดูบนเว็บไซต์อย่างเป็นทางการ
|
||||
|
||||
### เริ่มต้นใช้งาน
|
||||
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
🌐 Ito ay isang awtomatikong pagsasalin. Malugod na tinatanggap ang mga pagwawasto mula sa komunidad!
|
||||
|
||||
---
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-dark-mode.webp">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp" alt="Claude-Mem" width="400">
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
<a href="README.es.md">🇪🇸 Español</a> •
|
||||
<a href="README.de.md">🇩🇪 Deutsch</a> •
|
||||
<a href="README.fr.md">🇫🇷 Français</a> •
|
||||
<a href="README.he.md">🇮🇱 עברית</a> •
|
||||
<a href="README.ar.md">🇸🇦 العربية</a> •
|
||||
<a href="README.ru.md">🇷🇺 Русский</a> •
|
||||
<a href="README.pl.md">🇵🇱 Polski</a> •
|
||||
<a href="README.cs.md">🇨🇿 Čeština</a> •
|
||||
<a href="README.nl.md">🇳🇱 Nederlands</a> •
|
||||
<a href="README.tr.md">🇹🇷 Türkçe</a> •
|
||||
<a href="README.uk.md">🇺🇦 Українська</a> •
|
||||
<a href="README.vi.md">🇻🇳 Tiếng Việt</a> •
|
||||
<a href="README.tl.md">🇵🇭 Tagalog</a> •
|
||||
<a href="README.id.md">🇮🇩 Indonesia</a> •
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
<a href="README.el.md">🇬🇷 Ελληνικά</a> •
|
||||
<a href="README.hu.md">🇭🇺 Magyar</a> •
|
||||
<a href="README.fi.md">🇫🇮 Suomi</a> •
|
||||
<a href="README.da.md">🇩🇰 Dansk</a> •
|
||||
<a href="README.no.md">🇳🇴 Norsk</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">Sistema ng kompresyon ng persistent memory na ginawa para sa <a href="https://claude.com/claude-code" target="_blank">Claude Code</a>.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/version-6.5.0-green.svg" alt="Version">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg" alt="Node">
|
||||
</a>
|
||||
<a href="https://github.com/thedotmack/awesome-claude-code">
|
||||
<img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Claude Code">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/15496" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg" alt="thedotmack/claude-mem | Trendshift" width="250" height="55"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/cm-preview.gif" alt="Claude-Mem Preview" width="800">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#mabilis-na-pagsisimula">Mabilis na Pagsisimula</a> •
|
||||
<a href="#paano-ito-gumagana">Paano Ito Gumagana</a> •
|
||||
<a href="#mga-search-tool-ng-mcp">Mga Search Tool</a> •
|
||||
<a href="#dokumentasyon">Dokumentasyon</a> •
|
||||
<a href="#konpigurasyon">Konpigurasyon</a> •
|
||||
<a href="#pag-troubleshoot">Pag-troubleshoot</a> •
|
||||
<a href="#lisensya">Lisensya</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Pinapanatili ng Claude-Mem ang konteksto sa pagitan ng mga session sa pamamagitan ng awtomatikong pagkuha ng mga obserbasyon sa paggamit ng mga tool, pagbuo ng mga semantikong buod, at paggawa nitong available sa mga susunod na session. Dahil dito, napapanatili ni Claude ang tuloy-tuloy na kaalaman tungkol sa mga proyekto kahit matapos o muling kumonekta ang mga session.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Mabilis na Pagsisimula
|
||||
|
||||
Magsimula ng bagong Claude Code session sa terminal at ilagay ang mga sumusunod na command:
|
||||
|
||||
```
|
||||
/plugin marketplace add thedotmack/claude-mem
|
||||
|
||||
/plugin install claude-mem
|
||||
```
|
||||
|
||||
I-restart ang Claude Code. Awtomatikong lalabas sa mga bagong session ang konteksto mula sa mga nakaraang session.
|
||||
|
||||
**Mga Pangunahing Tampok:**
|
||||
|
||||
- 🧠 **Persistent Memory** - Nananatili ang konteksto sa pagitan ng mga session
|
||||
- 📊 **Progressive Disclosure** - Layered na pagkuha ng memory na may visibility ng token cost
|
||||
- 🔍 **Skill-Based Search** - I-query ang history ng proyekto gamit ang mem-search skill
|
||||
- 🖥️ **Web Viewer UI** - Real-time memory stream sa http://localhost:37777
|
||||
- 💻 **Claude Desktop Skill** - Maghanap sa memory mula sa Claude Desktop conversations
|
||||
- 🔒 **Privacy Control** - Gamitin ang `<private>` tags para hindi ma-store ang sensitibong nilalaman
|
||||
- ⚙️ **Context Configuration** - Mas pinong kontrol kung anong konteksto ang ini-inject
|
||||
- 🤖 **Automatic Operation** - Walang kailangang manual na intervention
|
||||
- 🔗 **Citations** - I-refer ang mga lumang obserbasyon gamit ang IDs (i-access sa http://localhost:37777/api/observation/{id} o tingnan lahat sa web viewer sa http://localhost:37777)
|
||||
- 🧪 **Beta Channel** - Subukan ang mga experimental feature tulad ng Endless Mode sa pamamagitan ng version switching
|
||||
|
||||
---
|
||||
|
||||
## Dokumentasyon
|
||||
|
||||
📚 **[Tingnan ang Buong Dokumentasyon](https://docs.claude-mem.ai/)** - I-browse sa opisyal na website
|
||||
|
||||
### Pagsisimula
|
||||
|
||||
- **[Gabay sa Pag-install](https://docs.claude-mem.ai/installation)** - Mabilis na pagsisimula at advanced installation
|
||||
- **[Gabay sa Paggamit](https://docs.claude-mem.ai/usage/getting-started)** - Paano awtomatikong gumagana ang Claude-Mem
|
||||
- **[Mga Search Tool](https://docs.claude-mem.ai/usage/search-tools)** - I-query ang history ng proyekto gamit ang natural language
|
||||
- **[Mga Beta Feature](https://docs.claude-mem.ai/beta-features)** - Subukan ang mga experimental feature tulad ng Endless Mode
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **[Context Engineering](https://docs.claude-mem.ai/context-engineering)** - Mga prinsipyo ng context optimization para sa AI agents
|
||||
- **[Progressive Disclosure](https://docs.claude-mem.ai/progressive-disclosure)** - Pilosopiya sa likod ng context priming strategy ng Claude-Mem
|
||||
|
||||
### Arkitektura
|
||||
|
||||
- **[Overview](https://docs.claude-mem.ai/architecture/overview)** - Mga bahagi ng sistema at daloy ng data
|
||||
- **[Architecture Evolution](https://docs.claude-mem.ai/architecture-evolution)** - Ang paglalakbay mula v3 hanggang v5
|
||||
- **[Hooks Architecture](https://docs.claude-mem.ai/hooks-architecture)** - Paano gumagamit ang Claude-Mem ng lifecycle hooks
|
||||
- **[Hooks Reference](https://docs.claude-mem.ai/architecture/hooks)** - 7 hook scripts, ipinaliwanag
|
||||
- **[Worker Service](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API at Bun management
|
||||
- **[Database](https://docs.claude-mem.ai/architecture/database)** - SQLite schema at FTS5 search
|
||||
- **[Search Architecture](https://docs.claude-mem.ai/architecture/search-architecture)** - Hybrid search gamit ang Chroma vector database
|
||||
|
||||
### Konpigurasyon at Pagbuo
|
||||
|
||||
- **[Konpigurasyon](https://docs.claude-mem.ai/configuration)** - Environment variables at settings
|
||||
- **[Pagbuo](https://docs.claude-mem.ai/development)** - Build, test, at contribution workflow
|
||||
- **[Pag-troubleshoot](https://docs.claude-mem.ai/troubleshooting)** - Karaniwang isyu at solusyon
|
||||
|
||||
---
|
||||
|
||||
## Paano Ito Gumagana
|
||||
|
||||
**Mga Pangunahing Bahagi:**
|
||||
|
||||
1. **5 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 hook scripts)
|
||||
2. **Smart Install** - Cached dependency checker (pre-hook script, hindi lifecycle hook)
|
||||
3. **Worker Service** - HTTP API sa port 37777 na may web viewer UI at 10 search endpoints, pinamamahalaan ng Bun
|
||||
4. **SQLite Database** - Nag-iimbak ng sessions, observations, summaries
|
||||
5. **mem-search Skill** - Natural language queries na may progressive disclosure
|
||||
6. **Chroma Vector Database** - Hybrid semantic + keyword search para sa matalinong pagkuha ng konteksto
|
||||
|
||||
Tingnan ang [Architecture Overview](https://docs.claude-mem.ai/architecture/overview) para sa detalye.
|
||||
|
||||
---
|
||||
|
||||
## Mga Search Tool ng MCP
|
||||
|
||||
Nagbibigay ang Claude-Mem ng intelligent memory search sa pamamagitan ng **5 MCP tools** na sumusunod sa token-efficient na **3-layer workflow pattern**:
|
||||
|
||||
**Ang 3-Layer Workflow:**
|
||||
|
||||
1. **`search`** - Kumuha ng compact index na may IDs (~50-100 tokens/result)
|
||||
2. **`timeline`** - Kumuha ng chronological context sa paligid ng mga interesting na result
|
||||
3. **`get_observations`** - Kunin ang full details PARA LANG sa na-filter na IDs (~500-1,000 tokens/result)
|
||||
|
||||
**Paano Ito Gumagana:**
|
||||
|
||||
- Gumagamit si Claude ng MCP tools para maghanap sa iyong memory
|
||||
- Magsimula sa `search` para makakuha ng index ng results
|
||||
- Gamitin ang `timeline` para makita ang nangyari sa paligid ng mga partikular na observation
|
||||
- Gamitin ang `get_observations` para kunin ang full details ng mga relevant na IDs
|
||||
- Gamitin ang `save_memory` para manual na mag-store ng importanteng impormasyon
|
||||
- **~10x tipid sa tokens** dahil nagfi-filter muna bago kunin ang full details
|
||||
|
||||
**Available na MCP Tools:**
|
||||
|
||||
1. **`search`** - Hanapin ang memory index gamit ang full-text queries, may filters (type/date/project)
|
||||
2. **`timeline`** - Kumuha ng chronological context sa paligid ng isang observation o query
|
||||
3. **`get_observations`** - Kumuha ng full observation details gamit ang IDs (laging i-batch ang maraming IDs)
|
||||
4. **`save_memory`** - Manual na mag-save ng memory/observation para sa semantic search
|
||||
5. **`__IMPORTANT`** - Workflow documentation (laging visible kay Claude)
|
||||
|
||||
**Halimbawa ng Paggamit:**
|
||||
|
||||
```typescript
|
||||
// Step 1: Search for index
|
||||
search(query="authentication bug", type="bugfix", limit=10)
|
||||
|
||||
// Step 2: Review index, identify relevant IDs (e.g., #123, #456)
|
||||
|
||||
// Step 3: Fetch full details
|
||||
get_observations(ids=[123, 456])
|
||||
|
||||
// Save important information manually
|
||||
save_memory(text="API requires auth header X-API-Key", title="API Auth")
|
||||
```
|
||||
|
||||
Tingnan ang [Search Tools Guide](https://docs.claude-mem.ai/usage/search-tools) para sa mas detalyadong mga halimbawa.
|
||||
|
||||
---
|
||||
|
||||
## Mga Beta Feature
|
||||
|
||||
May **beta channel** ang Claude-Mem na may mga experimental feature gaya ng **Endless Mode** (biomimetic memory architecture para sa mas mahahabang session). Magpalit sa pagitan ng stable at beta versions sa web viewer UI sa http://localhost:37777 → Settings.
|
||||
|
||||
Tingnan ang **[Dokumentasyon ng Mga Beta Feature](https://docs.claude-mem.ai/beta-features)** para sa detalye ng Endless Mode at kung paano ito subukan.
|
||||
|
||||
---
|
||||
|
||||
## Mga Pangangailangan ng Sistema
|
||||
|
||||
- **Node.js**: 18.0.0 o mas mataas
|
||||
- **Claude Code**: Pinakabagong bersyon na may plugin support
|
||||
- **Bun**: JavaScript runtime at process manager (auto-installed kung wala)
|
||||
- **uv**: Python package manager para sa vector search (auto-installed kung wala)
|
||||
- **SQLite 3**: Para sa persistent storage (kasama)
|
||||
|
||||
---
|
||||
|
||||
### Mga Tala sa Windows Setup
|
||||
|
||||
Kung makakita ka ng error gaya ng:
|
||||
|
||||
```powershell
|
||||
npm : The term 'npm' is not recognized as the name of a cmdlet
|
||||
```
|
||||
|
||||
Siguraduhing naka-install ang Node.js at npm at nakadagdag sa PATH. I-download ang pinakabagong Node.js installer mula sa https://nodejs.org at i-restart ang terminal matapos mag-install.
|
||||
|
||||
---
|
||||
|
||||
## Konpigurasyon
|
||||
|
||||
Pinamamahalaan ang settings sa `~/.claude-mem/settings.json` (auto-created na may defaults sa unang run). I-configure ang AI model, worker port, data directory, log level, at context injection settings.
|
||||
|
||||
Tingnan ang **[Gabay sa Konpigurasyon](https://docs.claude-mem.ai/configuration)** para sa lahat ng available na settings at mga halimbawa.
|
||||
|
||||
---
|
||||
|
||||
## Pagbuo
|
||||
|
||||
Tingnan ang **[Gabay nang pagbuo](https://docs.claude-mem.ai/development)** para sa pag build instructions, testing, at contribution workflow.
|
||||
|
||||
---
|
||||
|
||||
## Pag-troubleshoot
|
||||
|
||||
Kung may issue, ilarawan ang problema kay Claude at awtomatikong magdi-diagnose at magbibigay ng mga ayos ang troubleshoot skill.
|
||||
|
||||
Tingnan ang **[Troubleshooting Guide](https://docs.claude-mem.ai/troubleshooting)** para sa mga karaniwang isyu at solusyon.
|
||||
|
||||
---
|
||||
|
||||
## Bug Reports
|
||||
|
||||
Gumawa ng kumpletong bug reports gamit ang automated generator:
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
npm run bug-report
|
||||
```
|
||||
|
||||
## Pag-aambag
|
||||
|
||||
Malugod na tinatanggap ang mga kontribusyon! Pakisunod:
|
||||
|
||||
1. I-fork ang repository
|
||||
2. Gumawa ng feature branch
|
||||
3. Gawin ang mga pagbabago kasama ang tests
|
||||
4. I-update ang dokumentasyon
|
||||
5. Mag-submit ng Pull Request
|
||||
|
||||
Tingnan ang [Gabay nang pagbuo](https://docs.claude-mem.ai/development) para sa contribution workflow.
|
||||
|
||||
---
|
||||
|
||||
## Lisensya
|
||||
|
||||
Ang proyektong ito ay licensed sa ilalim ng **GNU Affero General Public License v3.0** (AGPL-3.0).
|
||||
|
||||
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
|
||||
|
||||
Tingnan ang [LICENSE](LICENSE) file para sa buong detalye.
|
||||
|
||||
**Ano ang ibig sabihin nito:**
|
||||
|
||||
- Maaari mong gamitin, baguhin, at ipamahagi ang software na ito nang libre
|
||||
- Kung babaguhin mo at i-deploy sa isang network server, kailangan mong gawing available ang iyong source code
|
||||
- Dapat ding naka-license sa AGPL-3.0 ang mga derivative works
|
||||
- WALANG WARRANTY para sa software na ito
|
||||
|
||||
**Tala tungkol sa Ragtime**: Ang `ragtime/` directory ay may hiwalay na lisensya sa ilalim ng **PolyForm Noncommercial License 1.0.0**. Tingnan ang [ragtime/LICENSE](ragtime/LICENSE) para sa detalye.
|
||||
|
||||
---
|
||||
|
||||
## Suporta
|
||||
|
||||
- **Dokumentasyon**: [docs/](docs/)
|
||||
- **Issues**: [GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
|
||||
- **Repository**: [github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
|
||||
- **Author**: Alex Newman ([@thedotmack](https://github.com/thedotmack))
|
||||
|
||||
---
|
||||
|
||||
**Built with Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -33,6 +34,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -125,7 +127,7 @@ Claude Code'u yeniden başlatın. Önceki oturumlardaki bağlam otomatik olarak
|
||||
|
||||
## Dokümantasyon
|
||||
|
||||
📚 **[Tam Dokümantasyonu Görüntüle](docs/)** - GitHub'da markdown dökümanlarına göz atın
|
||||
📚 **[Tam Dokümantasyonu Görüntüle](https://docs.claude-mem.ai/)** - Resmi web sitesinde göz atın
|
||||
|
||||
### Başlarken
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
## Документація
|
||||
|
||||
📚 **[Переглянути повну документацію](docs/)** - Переглядайте markdown документи на GitHub
|
||||
📚 **[Переглянути повну документацію](https://docs.claude-mem.ai/)** - Переглянути на офіційному сайті
|
||||
|
||||
### Початок роботи
|
||||
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
<section dir="rtl">
|
||||
🌐 یہ ایک خودکار ترجمہ ہے۔ کمیونٹی کی اصلاحات کا خیر مقدم ہے!
|
||||
|
||||
---
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-dark-mode.webp">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp" alt="Claude-Mem" width="400">
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<p align="center" dir="ltr">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
<a href="README.es.md">🇪🇸 Español</a> •
|
||||
<a href="README.de.md">🇩🇪 Deutsch</a> •
|
||||
<a href="README.fr.md">🇫🇷 Français</a>
|
||||
<a href="README.he.md">🇮🇱 עברית</a> •
|
||||
<a href="README.ar.md">🇸🇦 العربية</a> •
|
||||
<a href="README.ru.md">🇷🇺 Русский</a> •
|
||||
<a href="README.pl.md">🇵🇱 Polski</a> •
|
||||
<a href="README.cs.md">🇨🇿 Čeština</a> •
|
||||
<a href="README.nl.md">🇳🇱 Nederlands</a> •
|
||||
<a href="README.tr.md">🇹🇷 Türkçe</a> •
|
||||
<a href="README.uk.md">🇺🇦 Українська</a> •
|
||||
<a href="README.vi.md">🇻🇳 Tiếng Việt</a> •
|
||||
<a href="README.id.md">🇮🇩 Indonesia</a> •
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
<a href="README.el.md">🇬🇷 Ελληνικά</a> •
|
||||
<a href="README.hu.md">🇭🇺 Magyar</a> •
|
||||
<a href="README.fi.md">🇫🇮 Suomi</a> •
|
||||
<a href="README.da.md">🇩🇰 Dansk</a> •
|
||||
<a href="README.no.md">🇳🇴 Norsk</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center"><a href="https://claude.com/claude-code" target="_blank">Claude Code</a> کے لیے بنایا گیا مستقل میموری کمپریشن سسٹم۔</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/version-6.5.0-green.svg" alt="Version">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg" alt="Node">
|
||||
</a>
|
||||
<a href="https://github.com/thedotmack/awesome-claude-code">
|
||||
<img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Claude Code">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/15496" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg" alt="thedotmack/claude-mem | Trendshift" width="250" height="55"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/cm-preview.gif" alt="Claude-Mem Preview" width="800">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#تیز-رفتار-شروعات">تیز رفتار شروعات</a> •
|
||||
<a href="#یہ-کیسے-کام-کرتا-ہے">یہ کیسے کام کرتا ہے</a> •
|
||||
<a href="#تلاش-کے-اوزار">تلاش کے اوزار</a> •
|
||||
<a href="#دستاویزات">دستاویزات</a> •
|
||||
<a href="#ترتیبات">ترتیبات</a> •
|
||||
<a href="#مسائل-کی-تشخیص">مسائل کی تشخیص</a> •
|
||||
<a href="#لائسنس">لائسنس</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Claude-Mem خودکار طور پر ٹول کے استعمال کے بعد کے مشاہدات کو ریکارڈ کرتا ہے، سیمانٹک خلاصے تیار کرتا ہے اور انہیں مستقبل کے سیشنز میں دستیاب کرتا ہے تاکہ آپ سیشن میں براہ راست تناسب محفوظ رہے۔ یہ Claude کو سیشن ختم ہونے یا دوبارہ جڑنے کے بعد بھی منصوبے کے بارے میں معلومات کی مسلسلیت برقرار رکھنے کے قابل بناتا ہے۔
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## تیز رفتار شروعات
|
||||
|
||||
ٹرمنل میں نیا Claude Code سیشن شروع کریں اور ہیں کمانڈز درج کریں:
|
||||
|
||||
```
|
||||
> /plugin marketplace add thedotmack/claude-mem
|
||||
|
||||
> /plugin install claude-mem
|
||||
```
|
||||
|
||||
Claude Code کو دوبارہ شروع کریں۔ سابقہ سیشن کا تناسب خودکار طور پر نئے سیشن میں موجود ہوگا۔
|
||||
|
||||
**اہم خصوصیات:**
|
||||
|
||||
- 🧠 **مستقل میموری** - تناسب سیشن کے دوران برقرار رہتا ہے
|
||||
- 📊 **بتدریج ظہور** - لیئرڈ میموری کی بازیافت ٹوکن کی لاگت کی نمائندگی کے ساتھ
|
||||
- 🔍 **کمکردہ تلاش** - mem-search مہارت کے ساتھ اپنے منصوبے کی تاریخ میں تلاش کریں
|
||||
- 🖥️ **ویب ویور یو آئی** - http://localhost:37777 پر حقیقی وقت میموری اسٹریم
|
||||
- 💻 **Claude Desktop مہارت** - Claude Desktop بات چیت سے میموری تلاش کریں
|
||||
- 🔒 **رازداری کے کنٹرولز** - حساس مواد کو ذخیرہ سے خارج کرنے کے لیے `<private>` ٹیگ استعمال کریں
|
||||
- ⚙️ **تناسب کی ترتیبات** - کون سا تناسب انجیکٹ کیا جائے اس پر باریک کنٹرول
|
||||
- 🤖 **خودکار آپریشن** - کسی دستی مداخلت کی ضرورت نہیں
|
||||
- 🔗 **حوالہ** - ID کے ذریعے سابقہ مشاہدات کا حوالہ دیں (http://localhost:37777/api/observation/{id} کے ذریعے رسائی حاصل کریں یا تمام کو http://localhost:37777 پر ویب ویور میں دیکھیں)
|
||||
- 🧪 **بیٹا چینل** - ورژن تبدیل کرنے کے ذریعے Endless Mode جیسی تجرباتی خصوصیات آزمائیں
|
||||
|
||||
---
|
||||
|
||||
## دستاویزات
|
||||
|
||||
📚 **[مکمل دستاویزات دیکھیں](docs/)** - GitHub پر markdown ڈاکس کو براؤز کریں
|
||||
|
||||
### شروعات کرنا
|
||||
|
||||
- **[انسٹالیشن گائیڈ](https://docs.claude-mem.ai/installation)** - تیز رفتار شروعات اور اعلیٰ درجے کی انسٹالیشن
|
||||
- **[استعمال گائیڈ](https://docs.claude-mem.ai/usage/getting-started)** - Claude-Mem خودکار طور پر کیسے کام کرتا ہے
|
||||
- **[تلاش کے اوزار](https://docs.claude-mem.ai/usage/search-tools)** - قدرتی زبان کے ساتھ اپنے منصوبے کی تاریخ میں تلاش کریں
|
||||
- **[بیٹا خصوصیات](https://docs.claude-mem.ai/beta-features)** - Endless Mode جیسی تجرباتی خصوصیات آزمائیں
|
||||
|
||||
### بہترین طریقہ کار
|
||||
|
||||
- **[تناسب انجینیئرنگ](https://docs.claude-mem.ai/context-engineering)** - AI ایجنٹ کے تناسب کی اہمیت کے اصول
|
||||
- **[بتدریج ظہور](https://docs.claude-mem.ai/progressive-disclosure)** - Claude-Mem کے تناسب کی تیاری کی حکمت عملی کے پیچھے فلسفہ
|
||||
|
||||
### تعمیر
|
||||
|
||||
- **[جائزہ](https://docs.claude-mem.ai/architecture/overview)** - نظام کے اجزاء اور ڈیٹا کے بہاؤ
|
||||
- **[تعمیر کا ارتقاء](https://docs.claude-mem.ai/architecture-evolution)** - v3 سے v5 تک کا سفر
|
||||
- **[ہکس تعمیر](https://docs.claude-mem.ai/hooks-architecture)** - Claude-Mem لائف سائیکل ہکس کا استعمال کیسے کرتا ہے
|
||||
- **[ہکس حوالہ](https://docs.claude-mem.ai/architecture/hooks)** - 7 ہک اسکرپٹس کی تشریح
|
||||
- **[ورکر سروس](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API اور Bun انتظام
|
||||
- **[ڈیٹا بیس](https://docs.claude-mem.ai/architecture/database)** - SQLite اسکیما اور FTS5 تلاش
|
||||
- **[تلاش تعمیر](https://docs.claude-mem.ai/architecture/search-architecture)** - Chroma ویکٹر ڈیٹا بیس کے ساتھ ہائبرڈ تلاش
|
||||
|
||||
### ترتیبات اور ترقی
|
||||
|
||||
- **[ترتیبات](https://docs.claude-mem.ai/configuration)** - ماحول کے متغیرات اور سیٹنگز
|
||||
- **[ترقی](https://docs.claude-mem.ai/development)** - تعمیر، جانچ، حصہ داری
|
||||
- **[مسائل کی تشخیص](https://docs.claude-mem.ai/troubleshooting)** - عام مسائل اور حل
|
||||
|
||||
---
|
||||
|
||||
## یہ کیسے کام کرتا ہے
|
||||
|
||||
**اہم اجزاء:**
|
||||
|
||||
1. **5 لائف سائیکل ہکس** - SessionStart، UserPromptSubmit، PostToolUse، Stop، SessionEnd (6 ہک اسکرپٹس)
|
||||
2. **سمارٹ انسٹالیشن** - کیش شدہ منحصرات چیکر (پری ہک اسکرپٹ، لائف سائیکل ہک نہیں)
|
||||
3. **ورکر سروس** - ویب ویور UI اور 10 تلاش کے endpoints کے ساتھ پورٹ 37777 پر HTTP API، Bun کے ذریعے برتاؤ
|
||||
4. **SQLite ڈیٹا بیس** - سیشنز، مشاہدات، خلاصہ ذخیرہ کرتا ہے
|
||||
5. **mem-search مہارت** - بتدریج ظہور کے ساتھ قدرتی زبان کے سوالات
|
||||
6. **Chroma ویکٹر ڈیٹا بیس** - ہائبرڈ سیمانٹک + کلیدی لفظ تلاش ذہین تناسب کی بازیافت کے لیے
|
||||
|
||||
تفصیلات کے لیے [تعمیر کا جائزہ](https://docs.claude-mem.ai/architecture/overview) دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## MCP تلاش کے اوزار
|
||||
|
||||
Claude-Mem ٹوکن-موثر **3-لیئر ورک فلو پیٹرن** کی پیروی کرتے ہوئے **4 MCP اوزار** کے ذریعے ذہین میموری تلاش فراہم کرتا ہے:
|
||||
|
||||
**3-لیئر ورک فلو:**
|
||||
|
||||
1. **`search`** - IDs کے ساتھ کمپیکٹ انڈیکس حاصل کریں (~50-100 ٹوکن/نتیجہ)
|
||||
2. **`timeline`** - دلچسپ نتائج کے ارد گرد زمانی تناسب حاصل کریں
|
||||
3. **`get_observations`** - فلٹر شدہ IDs کے لیے صرف مکمل تفصیلات حاصل کریں (~500-1,000 ٹوکن/نتیجہ)
|
||||
|
||||
**یہ کیسے کام کرتا ہے:**
|
||||
- Claude آپ کی میموری میں تلاش کے لیے MCP اوزار استعمال کرتا ہے
|
||||
- نتائج کا انڈیکس حاصل کرنے کے لیے `search` سے شروع کریں
|
||||
- مخصوص مشاہدات کے ارد گرد کیا ہو رہا تھا دیکھنے کے لیے `timeline` استعمال کریں
|
||||
- متعلقہ IDs کے لیے مکمل تفصیلات حاصل کرنے کے لیے `get_observations` استعمال کریں
|
||||
- تفصیلات حاصل کرنے سے پہلے فلٹرنگ کے ذریعے **~10x ٹوکن کی بچت**
|
||||
|
||||
**دستیاب MCP اوزار:**
|
||||
|
||||
1. **`search`** - مکمل متن کی تلاش کے سوالات کے ساتھ میموری انڈیکس تلاش کریں، قسم/تاریخ/منصوبے کے لحاظ سے فلٹر کریں
|
||||
2. **`timeline`** - مخصوص مشاہدہ یا سوال کے ارد گرد زمانی تناسب حاصل کریں
|
||||
3. **`get_observations`** - IDs کے ذریعے مکمل مشاہدہ تفصیلات حاصل کریں (ہمیشہ متعدد IDs کو بیچ کریں)
|
||||
4. **`__IMPORTANT`** - ورک فلو دستاویزات (ہمیشہ Claude کو نظر آتی ہے)
|
||||
|
||||
**استعمال کی مثال:**
|
||||
|
||||
```typescript
|
||||
// مرحلہ 1: انڈیکس کے لیے تلاش کریں
|
||||
search(query="authentication bug", type="bugfix", limit=10)
|
||||
|
||||
// مرحلہ 2: انڈیکس کا جائزہ لیں، متعلقہ IDs کی شناخت کریں (مثلاً، #123, #456)
|
||||
|
||||
// مرحلہ 3: مکمل تفصیلات حاصل کریں
|
||||
get_observations(ids=[123, 456])
|
||||
```
|
||||
|
||||
تفصیلی مثالوں کے لیے [تلاش کے اوزار گائیڈ](https://docs.claude-mem.ai/usage/search-tools) دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## بیٹا خصوصیات
|
||||
|
||||
Claude-Mem ایک **بیٹا چینل** فراہم کرتا ہے جس میں **Endless Mode** جیسی تجرباتی خصوصیات ہیں (بڑھی ہوئی سیشنز کے لیے حیاتی نقل میموری کی تعمیر)۔ http://localhost:37777 → Settings میں ویب ویور UI سے مستحکم اور بیٹا ورژن کے درمیان سوئچ کریں۔
|
||||
|
||||
Endless Mode اور اسے کیسے آزمائیں اس کے بارے میں تفصیلات کے لیے **[بیٹا خصوصیات دستاویزات](https://docs.claude-mem.ai/beta-features)** دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## نظام کی ضروریات
|
||||
|
||||
- **Node.js**: 18.0.0 یا اس سے اوپر
|
||||
- **Claude Code**: پلگ ان سپورٹ کے ساتھ جدید ترین ورژن
|
||||
- **Bun**: JavaScript رن ٹائم اور پروسیس مینیجر (غیر موجود ہو تو خودکار طور پر انسٹال ہوگا)
|
||||
- **uv**: ویکٹر تلاش کے لیے Python پیکج مینیجر (غیر موجود ہو تو خودکار طور پر انسٹال ہوگا)
|
||||
- **SQLite 3**: مستقل اسٹوریج کے لیے (بنڈل شدہ)
|
||||
|
||||
---
|
||||
|
||||
## ترتیبات
|
||||
|
||||
سیٹنگز `~/.claude-mem/settings.json` میں منظم ہیں (پہلی رن میں ڈیفالٹ کے ساتھ خودکار طور پر بنائی جاتی ہے)۔ AI ماڈل، ورکر پورٹ، ڈیٹا ڈائریکٹری، لاگ لیول اور تناسب انجیکشن سیٹنگز کو ترتیب دیں۔
|
||||
|
||||
تمام دستیاب سیٹنگز اور مثالوں کے لیے **[ترتیبات گائیڈ](https://docs.claude-mem.ai/configuration)** دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## ترقی
|
||||
|
||||
تعمیر کی ہدایات، جانچ اور حصہ داری کے کام کے بہاؤ کے لیے **[ترقی گائیڈ](https://docs.claude-mem.ai/development)** دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## مسائل کی تشخیص
|
||||
|
||||
اگر مسائل کا سامنا ہو تو Claude کو مسئلہ بتائیں اور troubleshoot مہارت خودکار طور پر تشخیص دے گی اور حل فراہم کرے گی۔
|
||||
|
||||
عام مسائل اور حل کے لیے **[مسائل کی تشخیص گائیڈ](https://docs.claude-mem.ai/troubleshooting)** دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## خرابی کی رپورٹ
|
||||
|
||||
خودکار جنریٹر کے ساتھ تفصیلی خرابی کی رپورٹ تیار کریں:
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
npm run bug-report
|
||||
```
|
||||
|
||||
## حصہ داری
|
||||
|
||||
حصہ داری کا خیر مقدم ہے! براہ کرم:
|
||||
|
||||
1. رپوزیٹری کو فورک کریں
|
||||
2. ایک خصوصیت کی برانچ بنائیں
|
||||
3. ٹیسٹ کے ساتھ اپنی تبدیلیاں کریں
|
||||
4. دستاویزات کو اپڈیٹ کریں
|
||||
5. ایک Pull Request جمع کریں
|
||||
|
||||
حصہ داری کے کام کے بہاؤ کے لیے [ترقی گائیڈ](https://docs.claude-mem.ai/development) دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## لائسنس
|
||||
|
||||
یہ منصوبہ **GNU Affero General Public License v3.0** (AGPL-3.0) کے تحت لائسنس ہے۔
|
||||
|
||||
Copyright (C) 2025 Alex Newman (@thedotmack)۔ تمام حقوق محفوظ ہیں۔
|
||||
|
||||
مکمل تفصیلات کے لیے [LICENSE](LICENSE) فائل دیکھیں۔
|
||||
|
||||
**اس کا مطلب کیا ہے:**
|
||||
|
||||
- آپ اس سافٹ ویئر کو آزادی سے استعمال، تبدیل اور تقسیم کر سکتے ہیں
|
||||
- اگر آپ اسے تبدیل کریں اور نیٹ ورک سرور میں نشر کریں تو آپ کو اپنا سورس کوڈ دستیاب کرنا ہوگا
|
||||
- ماخوذ کام بھی AGPL-3.0 کے تحت لائسنس ہونے چاہیں
|
||||
- اس سافٹ ویئر کے لیے کوئی وارنٹی نہیں
|
||||
|
||||
**Ragtime کے بارے میں نوٹ**: `ragtime/` ڈائریکٹری الگ سے **PolyForm Noncommercial License 1.0.0** کے تحت لائسنس ہے۔ تفصیلات کے لیے [ragtime/LICENSE](ragtime/LICENSE) دیکھیں۔
|
||||
|
||||
---
|
||||
|
||||
## معاونت
|
||||
|
||||
- **دستاویزات**: [docs/](docs/)
|
||||
- **مسائل**: [GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
|
||||
- **رپوزیٹری**: [github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
|
||||
- **مصنف**: Alex Newman ([@thedotmack](https://github.com/thedotmack))
|
||||
|
||||
---
|
||||
|
||||
**Claude Agent SDK کے ساتھ بنایا گیا** | **Claude Code کے ذریعے طاقت ور** | **TypeScript کے ساتھ بنایا گیا**
|
||||
|
||||
</section>
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@ Khởi động lại Claude Code. Ngữ cảnh từ các phiên trước sẽ t
|
||||
|
||||
## Tài Liệu
|
||||
|
||||
📚 **[Xem Tài Liệu Đầy Đủ](docs/)** - Duyệt tài liệu markdown trên GitHub
|
||||
📚 **[Xem Tài Liệu Đầy Đủ](https://docs.claude-mem.ai/)** - Duyệt trên trang web chính thức
|
||||
|
||||
### Bắt Đầu
|
||||
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
🌐 這是自動翻譯。歡迎社群貢獻修正!
|
||||
|
||||
---
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-dark-mode.webp">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp" alt="Claude-Mem" width="400">
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
<a href="README.es.md">🇪🇸 Español</a> •
|
||||
<a href="README.de.md">🇩🇪 Deutsch</a> •
|
||||
<a href="README.fr.md">🇫🇷 Français</a>
|
||||
<a href="README.he.md">🇮🇱 עברית</a> •
|
||||
<a href="README.ar.md">🇸🇦 العربية</a> •
|
||||
<a href="README.ru.md">🇷🇺 Русский</a> •
|
||||
<a href="README.pl.md">🇵🇱 Polski</a> •
|
||||
<a href="README.cs.md">🇨🇿 Čeština</a> •
|
||||
<a href="README.nl.md">🇳🇱 Nederlands</a> •
|
||||
<a href="README.tr.md">🇹🇷 Türkçe</a> •
|
||||
<a href="README.uk.md">🇺🇦 Українська</a> •
|
||||
<a href="README.vi.md">🇻🇳 Tiếng Việt</a> •
|
||||
<a href="README.id.md">🇮🇩 Indonesia</a> •
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
<a href="README.el.md">🇬🇷 Ελληνικά</a> •
|
||||
<a href="README.hu.md">🇭🇺 Magyar</a> •
|
||||
<a href="README.fi.md">🇫🇮 Suomi</a> •
|
||||
<a href="README.da.md">🇩🇰 Dansk</a> •
|
||||
<a href="README.no.md">🇳🇴 Norsk</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">為 <a href="https://claude.com/claude-code" target="_blank">Claude Code</a> 打造的持久記憶壓縮系統</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/version-6.5.0-green.svg" alt="Version">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg" alt="Node">
|
||||
</a>
|
||||
<a href="https://github.com/thedotmack/awesome-claude-code">
|
||||
<img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Claude Code">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/15496" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg" alt="thedotmack/claude-mem | Trendshift" width="250" height="55"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/cm-preview.gif" alt="Claude-Mem Preview" width="800">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#快速開始">快速開始</a> •
|
||||
<a href="#運作原理">運作原理</a> •
|
||||
<a href="#mcp-搜尋工具">搜尋工具</a> •
|
||||
<a href="#文件">文件</a> •
|
||||
<a href="#設定">設定</a> •
|
||||
<a href="#疑難排解">疑難排解</a> •
|
||||
<a href="#授權條款">授權條款</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Claude-Mem 透過自動擷取工具使用觀察、產生語意摘要並在未來的工作階段中提供使用,無縫保留跨工作階段的脈絡。這使 Claude 即使在工作階段結束或重新連線後,仍能維持對專案的知識連續性。
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 快速開始
|
||||
|
||||
在終端機中開啟新的 Claude Code 工作階段,並輸入以下指令:
|
||||
|
||||
```
|
||||
> /plugin marketplace add thedotmack/claude-mem
|
||||
|
||||
> /plugin install claude-mem
|
||||
```
|
||||
|
||||
重新啟動 Claude Code。先前工作階段的脈絡將自動出現在新的工作階段中。
|
||||
|
||||
**主要功能:**
|
||||
|
||||
- 🧠 **持久記憶** - 脈絡跨工作階段保留
|
||||
- 📊 **漸進式揭露** - 具有 Token 成本可見性的分層記憶擷取
|
||||
- 🔍 **技能式搜尋** - 使用 mem-search 技能查詢專案歷史
|
||||
- 🖥️ **網頁檢視介面** - 在 http://localhost:37777 即時檢視記憶串流
|
||||
- 💻 **Claude Desktop 技能** - 從 Claude Desktop 對話中搜尋記憶
|
||||
- 🔒 **隱私控制** - 使用 `<private>` 標籤排除敏感內容的儲存
|
||||
- ⚙️ **脈絡設定** - 精細控制注入哪些脈絡
|
||||
- 🤖 **自動運作** - 無需手動介入
|
||||
- 🔗 **引用** - 使用 ID 參考過去的觀察(透過 http://localhost:37777/api/observation/{id} 存取,或在 http://localhost:37777 的網頁檢視器中檢視全部)
|
||||
- 🧪 **Beta 通道** - 透過版本切換試用 Endless Mode 等實驗性功能
|
||||
|
||||
---
|
||||
|
||||
## 文件
|
||||
|
||||
📚 **[檢視完整文件](docs/)** - 在 GitHub 上瀏覽 Markdown 文件
|
||||
|
||||
### 入門指南
|
||||
|
||||
- **[安裝指南](https://docs.claude-mem.ai/installation)** - 快速開始與進階安裝
|
||||
- **[使用指南](https://docs.claude-mem.ai/usage/getting-started)** - Claude-Mem 如何自動運作
|
||||
- **[搜尋工具](https://docs.claude-mem.ai/usage/search-tools)** - 使用自然語言查詢專案歷史
|
||||
- **[Beta 功能](https://docs.claude-mem.ai/beta-features)** - 試用 Endless Mode 等實驗性功能
|
||||
|
||||
### 最佳實務
|
||||
|
||||
- **[脈絡工程](https://docs.claude-mem.ai/context-engineering)** - AI 代理脈絡最佳化原則
|
||||
- **[漸進式揭露](https://docs.claude-mem.ai/progressive-disclosure)** - Claude-Mem 脈絡啟動策略背後的理念
|
||||
|
||||
### 架構
|
||||
|
||||
- **[概覽](https://docs.claude-mem.ai/architecture/overview)** - 系統元件與資料流程
|
||||
- **[架構演進](https://docs.claude-mem.ai/architecture-evolution)** - 從 v3 到 v5 的旅程
|
||||
- **[Hooks 架構](https://docs.claude-mem.ai/hooks-architecture)** - Claude-Mem 如何使用生命週期掛鉤
|
||||
- **[Hooks 參考](https://docs.claude-mem.ai/architecture/hooks)** - 7 個掛鉤腳本說明
|
||||
- **[Worker 服務](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API 與 Bun 管理
|
||||
- **[資料庫](https://docs.claude-mem.ai/architecture/database)** - SQLite 結構描述與 FTS5 搜尋
|
||||
- **[搜尋架構](https://docs.claude-mem.ai/architecture/search-architecture)** - 使用 Chroma 向量資料庫的混合搜尋
|
||||
|
||||
### 設定與開發
|
||||
|
||||
- **[設定](https://docs.claude-mem.ai/configuration)** - 環境變數與設定
|
||||
- **[開發](https://docs.claude-mem.ai/development)** - 建置、測試、貢獻
|
||||
- **[疑難排解](https://docs.claude-mem.ai/troubleshooting)** - 常見問題與解決方案
|
||||
|
||||
---
|
||||
|
||||
## 運作原理
|
||||
|
||||
**核心元件:**
|
||||
|
||||
1. **5 個生命週期掛鉤** - SessionStart、UserPromptSubmit、PostToolUse、Stop、SessionEnd(6 個掛鉤腳本)
|
||||
2. **智慧安裝** - 快取的相依性檢查器(pre-hook 腳本,非生命週期掛鉤)
|
||||
3. **Worker 服務** - 連接埠 37777 上的 HTTP API,含網頁檢視介面與 10 個搜尋端點,由 Bun 管理
|
||||
4. **SQLite 資料庫** - 儲存工作階段、觀察、摘要
|
||||
5. **mem-search 技能** - 具有漸進式揭露的自然語言查詢
|
||||
6. **Chroma 向量資料庫** - 用於智慧脈絡擷取的混合語意 + 關鍵字搜尋
|
||||
|
||||
詳情請參閱[架構概覽](https://docs.claude-mem.ai/architecture/overview)。
|
||||
|
||||
---
|
||||
|
||||
## MCP 搜尋工具
|
||||
|
||||
Claude-Mem 透過遵循 Token 高效的 **3 層工作流程模式**,以 **4 個 MCP 工具**提供智慧記憶搜尋:
|
||||
|
||||
**3 層工作流程:**
|
||||
|
||||
1. **`search`** - 取得精簡索引與 ID(每筆結果約 50-100 tokens)
|
||||
2. **`timeline`** - 取得有趣結果周圍的時間脈絡
|
||||
3. **`get_observations`** - 僅為過濾後的 ID 擷取完整詳情(每筆結果約 500-1,000 tokens)
|
||||
|
||||
**運作方式:**
|
||||
|
||||
- Claude 使用 MCP 工具搜尋您的記憶
|
||||
- 從 `search` 開始取得結果索引
|
||||
- 使用 `timeline` 檢視特定觀察周圍發生的事情
|
||||
- 使用 `get_observations` 擷取相關 ID 的完整詳情
|
||||
- 透過在擷取詳情前過濾,**節省約 10 倍 token**
|
||||
|
||||
**可用的 MCP 工具:**
|
||||
|
||||
1. **`search`** - 使用全文查詢搜尋記憶索引,依類型/日期/專案過濾
|
||||
2. **`timeline`** - 取得特定觀察或查詢周圍的時間脈絡
|
||||
3. **`get_observations`** - 依 ID 擷取完整觀察詳情(批次處理多個 ID)
|
||||
4. **`__IMPORTANT`** - 工作流程文件(Claude 永遠可見)
|
||||
|
||||
**使用範例:**
|
||||
|
||||
```typescript
|
||||
// 步驟 1:搜尋索引
|
||||
search(query="authentication bug", type="bugfix", limit=10)
|
||||
|
||||
// 步驟 2:檢閱索引,識別相關 ID(例如 #123、#456)
|
||||
|
||||
// 步驟 3:擷取完整詳情
|
||||
get_observations(ids=[123, 456])
|
||||
```
|
||||
|
||||
詳細範例請參閱[搜尋工具指南](https://docs.claude-mem.ai/usage/search-tools)。
|
||||
|
||||
---
|
||||
|
||||
## Beta 功能
|
||||
|
||||
Claude-Mem 提供具有實驗性功能的 **Beta 通道**,例如 **Endless Mode**(用於延長工作階段的仿生記憶架構)。在 http://localhost:37777 → Settings 的網頁檢視介面中切換穩定版與 Beta 版。
|
||||
|
||||
有關 Endless Mode 與如何試用的詳情,請參閱 **[Beta 功能文件](https://docs.claude-mem.ai/beta-features)**。
|
||||
|
||||
---
|
||||
|
||||
## 系統需求
|
||||
|
||||
- **Node.js**:18.0.0 或更高版本
|
||||
- **Claude Code**:具有外掛支援的最新版本
|
||||
- **Bun**:JavaScript 執行環境與程序管理員(如缺少將自動安裝)
|
||||
- **uv**:用於向量搜尋的 Python 套件管理員(如缺少將自動安裝)
|
||||
- **SQLite 3**:用於持久儲存(已內建)
|
||||
|
||||
---
|
||||
|
||||
## 設定
|
||||
|
||||
設定在 `~/.claude-mem/settings.json` 中管理(首次執行時自動以預設值建立)。設定 AI 模型、Worker 連接埠、資料目錄、日誌層級與脈絡注入設定。
|
||||
|
||||
所有可用設定與範例請參閱 **[設定指南](https://docs.claude-mem.ai/configuration)**。
|
||||
|
||||
---
|
||||
|
||||
## 開發
|
||||
|
||||
建置說明、測試與貢獻工作流程請參閱 **[開發指南](https://docs.claude-mem.ai/development)**。
|
||||
|
||||
---
|
||||
|
||||
## 疑難排解
|
||||
|
||||
如遇問題,向 Claude 描述問題,troubleshoot 技能將自動診斷並提供修正。
|
||||
|
||||
常見問題與解決方案請參閱 **[疑難排解指南](https://docs.claude-mem.ai/troubleshooting)**。
|
||||
|
||||
---
|
||||
|
||||
## 錯誤回報
|
||||
|
||||
使用自動產生器建立完整的錯誤回報:
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
npm run bug-report
|
||||
```
|
||||
|
||||
## 貢獻
|
||||
|
||||
歡迎貢獻!請依照以下步驟:
|
||||
|
||||
1. Fork 儲存庫
|
||||
2. 建立功能分支
|
||||
3. 加入測試並進行變更
|
||||
4. 更新文件
|
||||
5. 提交 Pull Request
|
||||
|
||||
貢獻工作流程請參閱[開發指南](https://docs.claude-mem.ai/development)。
|
||||
|
||||
---
|
||||
|
||||
## 授權條款
|
||||
|
||||
本專案採用 **GNU Affero 通用公共授權條款 v3.0**(AGPL-3.0)授權。
|
||||
|
||||
Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.
|
||||
|
||||
完整詳情請參閱 [LICENSE](LICENSE) 檔案。
|
||||
|
||||
**這代表什麼:**
|
||||
|
||||
- 您可以自由使用、修改與散佈此軟體
|
||||
- 如果您修改並部署於網路伺服器上,您必須公開您的原始碼
|
||||
- 衍生作品也必須採用 AGPL-3.0 授權
|
||||
- 本軟體不提供任何擔保
|
||||
|
||||
**關於 Ragtime 的說明**:`ragtime/` 目錄採用 **PolyForm Noncommercial License 1.0.0** 另行授權。詳情請參閱 [ragtime/LICENSE](ragtime/LICENSE)。
|
||||
|
||||
---
|
||||
|
||||
## 支援
|
||||
|
||||
- **文件**:[docs/](docs/)
|
||||
- **Issues**:[GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
|
||||
- **儲存庫**:[github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
|
||||
- **官方 X 帳號**:[@Claude_Memory](https://x.com/Claude_Memory)
|
||||
- **官方 Discord**:[加入 Discord](https://discord.com/invite/J4wttp9vDu)
|
||||
- **作者**:Alex Newman ([@thedotmack](https://github.com/thedotmack))
|
||||
|
||||
---
|
||||
|
||||
**使用 Claude Agent SDK 建置** | **由 Claude Code 驅動** | **以 TypeScript 開發**
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
@@ -34,6 +35,7 @@
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
@@ -126,7 +128,7 @@
|
||||
|
||||
## 文档
|
||||
|
||||
📚 **[查看完整文档](docs/)** - 在 GitHub 上浏览 Markdown 文档
|
||||
📚 **[查看完整文档](https://docs.claude-mem.ai/)** - 在官方网站浏览
|
||||
|
||||
### 入门指南
|
||||
|
||||
@@ -212,7 +214,7 @@ Claude-Mem 通过 mem-search 技能提供智能搜索,当您询问过去的工
|
||||
|
||||
Claude-Mem 提供**测试版渠道**,包含实验性功能,如**无尽模式**(用于扩展会话的仿生记忆架构)。从 Web 查看器界面 http://localhost:37777 → 设置 切换稳定版和测试版。
|
||||
|
||||
详见**[测试版功能文档](https://docs.claude-mem.ai/beta-features)**了解无尽模式的详细信息和试用方法。
|
||||
详见 **[测试版功能文档](https://docs.claude-mem.ai/beta-features)** 了解无尽模式的详细信息和试用方法。
|
||||
|
||||
---
|
||||
|
||||
@@ -230,13 +232,13 @@ Claude-Mem 提供**测试版渠道**,包含实验性功能,如**无尽模式**(
|
||||
|
||||
设置在 `~/.claude-mem/settings.json` 中管理(首次运行时自动创建默认设置)。可配置 AI 模型、worker 端口、数据目录、日志级别和上下文注入设置。
|
||||
|
||||
详见**[配置指南](https://docs.claude-mem.ai/configuration)**了解所有可用设置和示例。
|
||||
详见 **[配置指南](https://docs.claude-mem.ai/configuration)** 了解所有可用设置和示例。
|
||||
|
||||
---
|
||||
|
||||
## 开发
|
||||
|
||||
详见**[开发指南](https://docs.claude-mem.ai/development)**了解构建说明、测试和贡献工作流程。
|
||||
详见 **[开发指南](https://docs.claude-mem.ai/development)** 了解构建说明、测试和贡献工作流程。
|
||||
|
||||
---
|
||||
|
||||
@@ -244,7 +246,7 @@ Claude-Mem 提供**测试版渠道**,包含实验性功能,如**无尽模式**(
|
||||
|
||||
如果遇到问题,向 Claude 描述问题,troubleshoot 技能将自动诊断并提供修复方案。
|
||||
|
||||
详见**[故障排除指南](https://docs.claude-mem.ai/troubleshooting)**了解常见问题和解决方案。
|
||||
详见 **[故障排除指南](https://docs.claude-mem.ai/troubleshooting)** 了解常见问题和解决方案。
|
||||
|
||||
---
|
||||
|
||||
@@ -301,4 +303,4 @@ Copyright (C) 2025 Alex Newman (@thedotmack)。保留所有权利。
|
||||
|
||||
**使用 Claude Agent SDK 构建** | **由 Claude Code 驱动** | **使用 TypeScript 制作**
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
🌐 Esta é uma tradução manual por mig4ng. Correções da comunidade são bem-vindas!
|
||||
|
||||
---
|
||||
<h1 align="center">
|
||||
<br>
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-dark-mode.webp">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp" alt="Claude-Mem" width="400">
|
||||
</picture>
|
||||
</a>
|
||||
<br>
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
<a href="README.zh.md">🇨🇳 中文</a> •
|
||||
<a href="README.zh-tw.md">🇹🇼 繁體中文</a> •
|
||||
<a href="README.ja.md">🇯🇵 日本語</a> •
|
||||
<a href="README.pt.md">🇵🇹 Português</a> •
|
||||
<a href="README.pt-br.md">🇧🇷 Português (Brasil)</a> •
|
||||
<a href="README.ko.md">🇰🇷 한국어</a> •
|
||||
<a href="README.es.md">🇪🇸 Español</a> •
|
||||
<a href="README.de.md">🇩🇪 Deutsch</a> •
|
||||
<a href="README.fr.md">🇫🇷 Français</a>
|
||||
<a href="README.he.md">🇮🇱 עברית</a> •
|
||||
<a href="README.ar.md">🇸🇦 العربية</a> •
|
||||
<a href="README.ru.md">🇷🇺 Русский</a> •
|
||||
<a href="README.pl.md">🇵🇱 Polski</a> •
|
||||
<a href="README.cs.md">🇨🇿 Čeština</a> •
|
||||
<a href="README.nl.md">🇳🇱 Nederlands</a> •
|
||||
<a href="README.tr.md">🇹🇷 Türkçe</a> •
|
||||
<a href="README.uk.md">🇺🇦 Українська</a> •
|
||||
<a href="README.vi.md">🇻🇳 Tiếng Việt</a> •
|
||||
<a href="README.id.md">🇮🇩 Indonesia</a> •
|
||||
<a href="README.th.md">🇹🇭 ไทย</a> •
|
||||
<a href="README.hi.md">🇮🇳 हिन्दी</a> •
|
||||
<a href="README.bn.md">🇧🇩 বাংলা</a> •
|
||||
<a href="README.ur.md">🇵🇰 اردو</a> •
|
||||
<a href="README.ro.md">🇷🇴 Română</a> •
|
||||
<a href="README.sv.md">🇸🇪 Svenska</a> •
|
||||
<a href="README.it.md">🇮🇹 Italiano</a> •
|
||||
<a href="README.el.md">🇬🇷 Ελληνικά</a> •
|
||||
<a href="README.hu.md">🇭🇺 Magyar</a> •
|
||||
<a href="README.fi.md">🇫🇮 Suomi</a> •
|
||||
<a href="README.da.md">🇩🇰 Dansk</a> •
|
||||
<a href="README.no.md">🇳🇴 Norsk</a>
|
||||
</p>
|
||||
|
||||
<h4 align="center">Sistema de compressão de memória persistente construído para <a href="https://claude.com/claude-code" target="_blank">Claude Code</a>.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/version-6.5.0-green.svg" alt="Version">
|
||||
</a>
|
||||
<a href="package.json">
|
||||
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg" alt="Node">
|
||||
</a>
|
||||
<a href="https://github.com/thedotmack/awesome-claude-code">
|
||||
<img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Claude Code">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/15496" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg">
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg" alt="thedotmack/claude-mem | Trendshift" width="250" height="55"/>
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/thedotmack/claude-mem">
|
||||
<picture>
|
||||
<img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/cm-preview.gif" alt="Claude-Mem Preview" width="800">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#início-rápido">Início Rápido</a> •
|
||||
<a href="#como-funciona">Como Funciona</a> •
|
||||
<a href="#ferramentas-de-procura-mcp">Ferramentas de Procura</a> •
|
||||
<a href="#documentação">Documentação</a> •
|
||||
<a href="#configuração">Configuração</a> •
|
||||
<a href="#solução-de-problemas">Solução de Problemas</a> •
|
||||
<a href="#licença">Licença</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Claude-Mem preserva o contexto perfeitamente entre sessões, capturando automaticamente observações de uso de ferramentas, gerando resumos semânticos e disponibilizando-os para sessões futuras. Isso permite que Claude mantenha a continuidade do conhecimento sobre projetos mesmo após o término ou reconexão de sessões.
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Início Rápido
|
||||
|
||||
Inicie uma nova sessão do Claude Code no terminal e digite os seguintes comandos:
|
||||
|
||||
```
|
||||
> /plugin marketplace add thedotmack/claude-mem
|
||||
|
||||
> /plugin install claude-mem
|
||||
```
|
||||
|
||||
Reinicie o Claude Code. O contexto de sessões anteriores aparecerá automaticamente em novas sessões.
|
||||
|
||||
**Principais Recursos:**
|
||||
|
||||
- 🧠 **Memória Persistente** - O contexto sobrevive entre sessões
|
||||
- 📊 **Divulgação Progressiva** - Recuperação de memória em camadas com visibilidade de custo de tokens
|
||||
- 🔍 **Procura Baseada em Skill** - Consulte seu histórico de projeto com a skill mem-search
|
||||
- 🖥️ **Interface Web de Visualização** - Fluxo de memória em tempo real em http://localhost:37777
|
||||
- 💻 **Skill para Claude Desktop** - Busque memória em conversas do Claude Desktop
|
||||
- 🔒 **Controle de Privacidade** - Use tags `<private>` para excluir conteúdo sensível do armazenamento
|
||||
- ⚙️ **Configuração de Contexto** - Controle refinado sobre qual contexto é injetado
|
||||
- 🤖 **Operação Automática** - Nenhuma intervenção manual necessária
|
||||
- 🔗 **Citações** - Referencie observações passadas com IDs (acesse via http://localhost:37777/api/observation/{id} ou visualize todas no visualizador web em http://localhost:37777)
|
||||
- 🧪 **Canal Beta** - Experimente recursos experimentais como o Endless Mode através da troca de versões
|
||||
|
||||
---
|
||||
|
||||
## Documentação
|
||||
|
||||
📚 **[Ver Documentação Completa](https://docs.claude-mem.ai/)** - Navegar no site oficial
|
||||
|
||||
### Começando
|
||||
|
||||
- **[Guia de Instalação](https://docs.claude-mem.ai/installation)** - Início rápido e instalação avançada
|
||||
- **[Guia de Uso](https://docs.claude-mem.ai/usage/getting-started)** - Como Claude-Mem funciona automaticamente
|
||||
- **[Ferramentas de Procura](https://docs.claude-mem.ai/usage/search-tools)** - Consulte seu histórico de projeto com linguagem natural
|
||||
- **[Recursos Beta](https://docs.claude-mem.ai/beta-features)** - Experimente recursos experimentais como o Endless Mode
|
||||
|
||||
### Melhores Práticas
|
||||
|
||||
- **[Engenharia de Contexto](https://docs.claude-mem.ai/context-engineering)** - Princípios de otimização de contexto para agentes de IA
|
||||
- **[Divulgação Progressiva](https://docs.claude-mem.ai/progressive-disclosure)** - Filosofia por trás da estratégia de preparação de contexto do Claude-Mem
|
||||
|
||||
### Arquitetura
|
||||
|
||||
- **[Visão Geral](https://docs.claude-mem.ai/architecture/overview)** - Componentes do sistema e fluxo de dados
|
||||
- **[Evolução da Arquitetura](https://docs.claude-mem.ai/architecture-evolution)** - A jornada da v3 à v5
|
||||
- **[Arquitetura de Hooks](https://docs.claude-mem.ai/hooks-architecture)** - Como Claude-Mem usa hooks de ciclo de vida
|
||||
- **[Referência de Hooks](https://docs.claude-mem.ai/architecture/hooks)** - 7 scripts de hook explicados
|
||||
- **[Serviço Worker](https://docs.claude-mem.ai/architecture/worker-service)** - API HTTP e gerenciamento do Bun
|
||||
- **[Banco de Dados](https://docs.claude-mem.ai/architecture/database)** - Schema SQLite e Procura FTS5
|
||||
- **[Arquitetura de Procura](https://docs.claude-mem.ai/architecture/search-architecture)** - Procura híbrida com banco de dados vetorial Chroma
|
||||
|
||||
### Configuração e Desenvolvimento
|
||||
|
||||
- **[Configuração](https://docs.claude-mem.ai/configuration)** - Variáveis de ambiente e configurações
|
||||
- **[Desenvolvimento](https://docs.claude-mem.ai/development)** - Build, testes e contribuição
|
||||
- **[Solução de Problemas](https://docs.claude-mem.ai/troubleshooting)** - Problemas comuns e soluções
|
||||
|
||||
---
|
||||
|
||||
## Como Funciona
|
||||
|
||||
**Componentes Principais:**
|
||||
|
||||
1. **5 Hooks de Ciclo de Vida** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 scripts de hook)
|
||||
2. **Instalação Inteligente** - Verificador de dependências em cache (script pré-hook, não um hook de ciclo de vida)
|
||||
3. **Serviço Worker** - API HTTP na porta 37777 com interface de visualização web e 10 endpoints de Procura, gerenciado pelo Bun
|
||||
4. **Banco de Dados SQLite** - Armazena sessões, observações, resumos
|
||||
5. **Skill mem-search** - Consultas em linguagem natural com divulgação progressiva
|
||||
6. **Banco de Dados Vetorial Chroma** - Procura híbrida semântica + palavra-chave para recuperação inteligente de contexto
|
||||
|
||||
Veja [Visão Geral da Arquitetura](https://docs.claude-mem.ai/architecture/overview) para detalhes.
|
||||
|
||||
---
|
||||
|
||||
## Skill mem-search
|
||||
|
||||
Claude-Mem fornece Procura inteligente através da skill mem-search que se auto-invoca quando você pergunta sobre trabalhos anteriores:
|
||||
|
||||
**Como Funciona:**
|
||||
- Pergunte naturalmente: *"O que fizemos na última sessão?"* ou *"Já corrigimos esse bug antes?"*
|
||||
- Claude invoca automaticamente a skill mem-search para encontrar contexto relevante
|
||||
|
||||
**Operações de Procura Disponíveis:**
|
||||
|
||||
1. **Search Observations** - Procura de texto completo em observações
|
||||
2. **Search Sessions** - Procura de texto completo em resumos de sessão
|
||||
3. **Search Prompts** - Procura em solicitações brutas do usuário
|
||||
4. **By Concept** - Encontre por tags de conceito (discovery, problem-solution, pattern, etc.)
|
||||
5. **By File** - Encontre observações que referenciam arquivos específicos
|
||||
6. **By Type** - Encontre por tipo (decision, bugfix, feature, refactor, discovery, change)
|
||||
7. **Recent Context** - Obtenha contexto de sessão recente para um projeto
|
||||
8. **Timeline** - Obtenha linha do tempo unificada de contexto em torno de um ponto específico no tempo
|
||||
9. **Timeline by Query** - Busque observações e obtenha contexto de linha do tempo em torno da melhor correspondência
|
||||
10. **API Help** - Obtenha documentação da API de Procura
|
||||
|
||||
**Exemplos de Consultas em Linguagem Natural:**
|
||||
|
||||
```
|
||||
"Quais bugs corrigimos na última sessão?"
|
||||
"Como implementamos a autenticação?"
|
||||
"Quais mudanças foram feitas em worker-service.ts?"
|
||||
"Mostre-me trabalhos recentes neste projeto"
|
||||
"O que estava acontecendo quando adicionamos a interface de visualização?"
|
||||
```
|
||||
|
||||
Veja [Guia de Ferramentas de Procura](https://docs.claude-mem.ai/usage/search-tools) para exemplos detalhados.
|
||||
|
||||
---
|
||||
|
||||
## Recursos Beta
|
||||
|
||||
Claude-Mem oferece um **canal beta** com recursos experimentais como **Endless Mode** (arquitetura de memória biomimética para sessões estendidas). Alterne entre versões estável e beta pela interface de visualização web em http://localhost:37777 → Settings.
|
||||
|
||||
Veja **[Documentação de Recursos Beta](https://docs.claude-mem.ai/beta-features)** para detalhes sobre o Endless Mode e como experimentá-lo.
|
||||
|
||||
---
|
||||
|
||||
## Requisitos do Sistema
|
||||
|
||||
- **Node.js**: 18.0.0 ou superior
|
||||
- **Claude Code**: Versão mais recente com suporte a plugins
|
||||
- **Bun**: Runtime JavaScript e gerenciador de processos (instalado automaticamente se ausente)
|
||||
- **uv**: Gerenciador de pacotes Python para Procura vetorial (instalado automaticamente se ausente)
|
||||
- **SQLite 3**: Para armazenamento persistente (incluído)
|
||||
|
||||
---
|
||||
|
||||
## Configuração
|
||||
|
||||
As configurações são gerenciadas em `~/.claude-mem/settings.json` (criado automaticamente com valores padrão na primeira execução). Configure modelo de IA, porta do worker, diretório de dados, nível de log e configurações de injeção de contexto.
|
||||
|
||||
Veja o **[Guia de Configuração](https://docs.claude-mem.ai/configuration)** para todas as configurações disponíveis e exemplos.
|
||||
|
||||
---
|
||||
|
||||
## Desenvolvimento
|
||||
|
||||
Veja o **[Guia de Desenvolvimento](https://docs.claude-mem.ai/development)** para instruções de build, testes e fluxo de contribuição.
|
||||
|
||||
---
|
||||
|
||||
## Solução de Problemas
|
||||
|
||||
Se você estiver enfrentando problemas, descreva o problema para Claude e a skill troubleshoot diagnosticará automaticamente e fornecerá correções.
|
||||
|
||||
Veja o **[Guia de Solução de Problemas](https://docs.claude-mem.ai/troubleshooting)** para problemas comuns e soluções.
|
||||
|
||||
---
|
||||
|
||||
## Relatos de Bug
|
||||
|
||||
Crie relatos de bug abrangentes com o gerador automatizado:
|
||||
|
||||
```bash
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
npm run bug-report
|
||||
```
|
||||
|
||||
## Contribuindo
|
||||
|
||||
Contribuições são bem-vindas! Por favor:
|
||||
|
||||
1. Faça um fork do repositório
|
||||
2. Crie uma branch de feature
|
||||
3. Faça suas alterações com testes
|
||||
4. Atualize a documentação
|
||||
5. Envie um Pull Request
|
||||
|
||||
Veja [Guia de Desenvolvimento](https://docs.claude-mem.ai/development) para o fluxo de contribuição.
|
||||
|
||||
---
|
||||
|
||||
## Licença
|
||||
|
||||
Este projeto está licenciado sob a **GNU Affero General Public License v3.0** (AGPL-3.0).
|
||||
|
||||
Copyright (C) 2025 Alex Newman (@thedotmack). Todos os direitos reservados.
|
||||
|
||||
Veja o arquivo [LICENSE](LICENSE) para detalhes completos.
|
||||
|
||||
**O Que Isso Significa:**
|
||||
|
||||
- Você pode usar, modificar e distribuir este software livremente
|
||||
- Se você modificar e implantar em um servidor de rede, você deve disponibilizar seu código-fonte
|
||||
- Trabalhos derivados também devem ser licenciados sob AGPL-3.0
|
||||
- NÃO HÁ GARANTIA para este software
|
||||
|
||||
**Nota sobre Ragtime**: O diretório `ragtime/` é licenciado separadamente sob a **PolyForm Noncommercial License 1.0.0**. Veja [ragtime/LICENSE](ragtime/LICENSE) para detalhes.
|
||||
|
||||
---
|
||||
|
||||
## Suporte
|
||||
|
||||
- **Documentação**: [docs/](docs/)
|
||||
- **Issues**: [GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
|
||||
- **Repositório**: [github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
|
||||
- **Autor**: Alex Newman ([@thedotmack](https://github.com/thedotmack))
|
||||
|
||||
---
|
||||
|
||||
**Construído com Claude Agent SDK** | **Desenvolvido por Claude Code** | **Feito com TypeScript** | **Editado por mig4ng**
|
||||
@@ -85,4 +85,4 @@ npx mintlify dev
|
||||
|
||||
**Simple Rule**:
|
||||
- `/docs/public/` = Official user documentation (Mintlify .mdx files) ← YOU ARE HERE
|
||||
- `/docs/context/` = Internal docs, plans, references, audits
|
||||
- `/docs/context/` = Internal docs, plans, references, audits
|
||||
@@ -177,7 +177,7 @@ graph TB
|
||||
|
||||
| Stage | Hook | Trigger | Purpose |
|
||||
|-------|------|---------|---------|
|
||||
| **1. SessionStart** | `context-hook.js` + `user-message-hook.js` | User opens Claude Code | Inject prior context, show UI messages |
|
||||
| **1. SessionStart** | `context-hook.js` | User opens Claude Code | Inject prior context silently |
|
||||
| **2. UserPromptSubmit** | `new-hook.js` | User submits a prompt | Create/get session, save prompt, init worker |
|
||||
| **3. PostToolUse** | `save-hook.js` | Claude uses any tool | Queue observation for AI compression |
|
||||
| **4. Stop** | `summary-hook.js` | User stops asking questions | Generate session summary |
|
||||
@@ -194,12 +194,16 @@ Hooks are configured in `plugin/hooks/hooks.json`:
|
||||
"matcher": "startup|clear|compact",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
|
||||
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/smart-install.js",
|
||||
"timeout": 300
|
||||
}, {
|
||||
"type": "command",
|
||||
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js",
|
||||
"timeout": 10
|
||||
"command": "bun ${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs start",
|
||||
"timeout": 60
|
||||
}, {
|
||||
"type": "command",
|
||||
"command": "bun ${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js",
|
||||
"timeout": 60
|
||||
}]
|
||||
}],
|
||||
"UserPromptSubmit": [{
|
||||
@@ -242,8 +246,13 @@ Hooks are configured in `plugin/hooks/hooks.json`:
|
||||
**Timing**: When user opens Claude Code or resumes session
|
||||
|
||||
**Hooks Triggered** (in order):
|
||||
1. `context-hook.js` - Fetches and injects prior session context
|
||||
2. `user-message-hook.js` - Displays context info to user via stderr
|
||||
1. `smart-install.js` - Ensures dependencies are installed
|
||||
2. `worker-service.cjs start` - Starts the worker service
|
||||
3. `context-hook.js` - Fetches and silently injects prior session context
|
||||
|
||||
<Note>
|
||||
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
|
||||
</Note>
|
||||
|
||||
### Sequence Diagram
|
||||
|
||||
@@ -306,19 +315,6 @@ sequenceDiagram
|
||||
|
||||
**Implementation**: `src/hooks/context-hook.ts`
|
||||
|
||||
### User Message Hook (`user-message-hook.js`)
|
||||
|
||||
**Purpose**: Display helpful user messages during first-time setup or when viewing context.
|
||||
|
||||
**Behavior**:
|
||||
- Shows first-time setup message when `node_modules` is missing
|
||||
- Displays formatted context information with colors
|
||||
- Provides tips for using claude-mem effectively
|
||||
- Shows link to viewer UI (`http://localhost:37777`)
|
||||
- Uses stderr as communication channel (only output available in Claude Code UI)
|
||||
|
||||
**Implementation**: `src/hooks/user-message-hook.ts`
|
||||
|
||||
---
|
||||
|
||||
## Stage 2: UserPromptSubmit
|
||||
|
||||
@@ -45,19 +45,19 @@ Hook (stdin) → Database → Worker Service → SDK Processor → Database →
|
||||
4. **Output**: Processed summaries written back to database
|
||||
5. **Retrieval**: Next session's context hook reads summaries from database
|
||||
|
||||
### Search Pipeline (v5.4.0+)
|
||||
### Search Pipeline
|
||||
```
|
||||
User Query → mem-search Skill Invoked → HTTP API → SessionSearch Service → FTS5 Database → Search Results → Claude
|
||||
User Query → MCP Tools Invoked → HTTP API → SessionSearch Service → FTS5 Database → Search Results → Claude
|
||||
```
|
||||
|
||||
1. **User Query**: User asks naturally: "What bugs did we fix?"
|
||||
2. **Skill Invoked**: Claude recognizes intent and invokes mem-search skill
|
||||
3. **HTTP API**: Skill uses curl to call HTTP endpoint (e.g., `/api/search/observations`)
|
||||
2. **MCP Tools Invoked**: Claude recognizes intent and invokes MCP search tools
|
||||
3. **HTTP API**: MCP tools call HTTP endpoint (e.g., `/api/search/observations`)
|
||||
4. **SessionSearch**: Worker service queries FTS5 virtual tables
|
||||
5. **Format**: Results formatted and returned to skill
|
||||
5. **Format**: Results formatted and returned via MCP
|
||||
6. **Return**: Claude presents formatted results to user
|
||||
|
||||
**Token Savings**: ~2,250 tokens per session vs MCP approach through progressive disclosure
|
||||
Uses 3-layer progressive disclosure: search → timeline → get_observations
|
||||
|
||||
## Session Lifecycle
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Settings are managed in `~/.claude-mem/settings.json`. The file is auto-created
|
||||
| `CLAUDE_MEM_MODE` | `code` | Active mode profile (e.g., `code--es`, `email-investigation`) |
|
||||
| `CLAUDE_MEM_CONTEXT_OBSERVATIONS` | `50` | Number of observations to inject |
|
||||
| `CLAUDE_MEM_WORKER_PORT` | `37777` | Worker service port |
|
||||
| `CLAUDE_MEM_WORKER_HOST` | `127.0.0.1` | Worker service host address |
|
||||
| `CLAUDE_MEM_SKIP_TOOLS` | `ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion` | Comma-separated tools to exclude from observations |
|
||||
|
||||
### Gemini Provider Settings
|
||||
@@ -25,7 +26,7 @@ Settings are managed in `~/.claude-mem/settings.json`. The file is auto-created
|
||||
| Setting | Default | Description |
|
||||
|-------------------------------|---------------------------------|---------------------------------------|
|
||||
| `CLAUDE_MEM_GEMINI_API_KEY` | — | Gemini API key ([get free key](https://aistudio.google.com/app/apikey)) |
|
||||
| `CLAUDE_MEM_GEMINI_MODEL` | `gemini-2.5-flash-lite` | Gemini model: `gemini-2.5-flash-lite`, `gemini-2.5-flash`, `gemini-3-flash` |
|
||||
| `CLAUDE_MEM_GEMINI_MODEL` | `gemini-2.5-flash-lite` | Gemini model: `gemini-2.5-flash-lite`, `gemini-2.5-flash`, `gemini-3-flash-preview` |
|
||||
|
||||
See [Gemini Provider](usage/gemini-provider) for detailed configuration and free tier information.
|
||||
|
||||
@@ -189,19 +190,16 @@ Hooks are configured in `plugin/hooks/hooks.json`:
|
||||
}
|
||||
```
|
||||
|
||||
### Search Configuration (v5.4.0+)
|
||||
### Search Configuration
|
||||
|
||||
**Migration Note**: As of v5.4.0, Claude-Mem uses skill-based search instead of MCP tools. As of v5.5.0, the skill was renamed to "mem-search" for better scope differentiation.
|
||||
Claude-Mem provides MCP search tools for querying your project history.
|
||||
|
||||
**Previous (v5.3.x and earlier)**: MCP search server with 9 tools (~2,500 tokens per session)
|
||||
**Current (v5.4.0+)**: mem-search skill with HTTP API (~250 tokens per session)
|
||||
**No configuration required** - MCP tools are automatically available in Claude Code sessions.
|
||||
|
||||
**No configuration required** - the mem-search skill is automatically available in Claude Code sessions.
|
||||
|
||||
Search operations are now provided via:
|
||||
- **Skill**: `plugin/skills/mem-search/SKILL.md` (auto-invoked when users ask about past work)
|
||||
Search operations are provided via:
|
||||
- **MCP Server**: 3 tools (search, timeline, get_observations) with progressive disclosure
|
||||
- **HTTP API**: 10 endpoints on worker service port 37777
|
||||
- **Progressive Disclosure**: Full instructions loaded on-demand only when needed
|
||||
- **Auto-Invocation**: Claude recognizes natural language queries about past work
|
||||
|
||||
## Version Channel
|
||||
|
||||
@@ -229,6 +227,16 @@ Endless Mode is experimental and slower than standard mode. See [Beta Features](
|
||||
|
||||
Worker service is managed by Bun as a background process. The worker auto-starts on first session and runs continuously in the background.
|
||||
|
||||
## Folder Context Files
|
||||
|
||||
Claude-mem can automatically generate `CLAUDE.md` files in your project folders with activity timelines. This feature is disabled by default.
|
||||
|
||||
| Setting | Default | Description |
|
||||
|---------|---------|-------------|
|
||||
| `CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED` | `false` | Enable auto-generation of folder CLAUDE.md files |
|
||||
|
||||
See [Folder Context Files](usage/folder-context) for full documentation on how this feature works, configuration options, and git integration recommendations.
|
||||
|
||||
## Context Injection Configuration
|
||||
|
||||
Claude-Mem injects past observations into each new session, giving Claude awareness of recent work. You can configure exactly what gets injected using the **Context Settings Modal**.
|
||||
|
||||
@@ -103,7 +103,7 @@ Open http://localhost:37777 to see the memory viewer.
|
||||
|-------|---------------|-------|
|
||||
| `gemini-2.5-flash-lite` | 10 (4,000 with billing) | **Default.** Fastest, highest free tier RPM |
|
||||
| `gemini-2.5-flash` | 5 (1,000 with billing) | Higher capability |
|
||||
| `gemini-3-flash` | 5 (1,000 with billing) | Latest model |
|
||||
| `gemini-3-flash-preview` | 5 (1,000 with billing) | Latest model |
|
||||
|
||||
To change the model, update your settings:
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"usage/private-tags",
|
||||
"usage/export-import",
|
||||
"usage/manual-recovery",
|
||||
"usage/folder-context",
|
||||
"beta-features",
|
||||
"endless-mode"
|
||||
]
|
||||
@@ -72,7 +73,8 @@
|
||||
"modes",
|
||||
"development",
|
||||
"troubleshooting",
|
||||
"platform-integration"
|
||||
"platform-integration",
|
||||
"openclaw-integration"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,11 +22,15 @@ Claude-Mem is fundamentally a **hook-driven system**. Every piece of functionali
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ CLAUDE-MEM SYSTEM │
|
||||
│ │
|
||||
│ Smart Context User New Obs │
|
||||
│ Install Inject Message Session Capture │
|
||||
│ Smart Worker Context New Obs │
|
||||
│ Install Start Inject Session Capture │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
<Note>
|
||||
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
|
||||
</Note>
|
||||
|
||||
**Key insight:** Claude-Mem doesn't interrupt or modify Claude Code's behavior. It observes from the outside and provides value through lifecycle hooks.
|
||||
|
||||
---
|
||||
@@ -68,9 +72,9 @@ Claude Code's hook system provides exactly what we need:
|
||||
|
||||
---
|
||||
|
||||
## The Six Hook Scripts + Pre-Hook
|
||||
## The Hook Scripts
|
||||
|
||||
Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-hook script for dependency management. SessionStart runs 2 hooks in sequence (after the pre-hook script).
|
||||
Claude-Mem uses lifecycle hook scripts across 5 lifecycle events. SessionStart runs 3 hooks in sequence: smart-install, worker-service start, and context-hook.
|
||||
|
||||
### Pre-Hook: Smart Install (Before SessionStart)
|
||||
|
||||
@@ -148,63 +152,14 @@ Claude-Mem uses 6 lifecycle hook scripts across 5 lifecycle events, plus 1 pre-h
|
||||
|----|------|---|-------|--------|
|
||||
| #2586 | 12:58 AM | 🔵 | Context hook file empty | ~51 |
|
||||
|
||||
*Use mem-search skill to access full details*
|
||||
*Use MCP search tools to access full details*
|
||||
```
|
||||
|
||||
**Source:** `src/hooks/context-hook.ts` → `plugin/scripts/context-hook.js`
|
||||
|
||||
---
|
||||
|
||||
### Hook 2: SessionStart - User Message
|
||||
|
||||
**Purpose:** Display helpful user messages during first-time setup
|
||||
|
||||
**When:** Claude Code starts (runs after context-hook)
|
||||
|
||||
**What it does:**
|
||||
1. Checks if dependencies are installed
|
||||
2. Shows first-time setup message if needed
|
||||
3. Displays formatted context information with colors
|
||||
4. Shows link to viewer UI (http://localhost:37777)
|
||||
5. Exits with code 3 (informational, not error)
|
||||
|
||||
**Configuration:**
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [{
|
||||
"matcher": "startup|clear|compact",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "node ${CLAUDE_PLUGIN_ROOT}/scripts/user-message-hook.js",
|
||||
"timeout": 10
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Output Example:**
|
||||
```
|
||||
📝 Claude-Mem Context Loaded
|
||||
ℹ️ Note: This appears as stderr but is informational only
|
||||
|
||||
[Context details with colors...]
|
||||
|
||||
📺 Watch live in browser http://localhost:37777/ (New! v5.1)
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
- ✅ User-friendly first-time experience
|
||||
- ✅ Visual context display
|
||||
- ✅ Links to viewer UI
|
||||
- ✅ Non-intrusive (exit code 3)
|
||||
|
||||
**Source:** `plugin/scripts/user-message-hook.js` (minified)
|
||||
|
||||
---
|
||||
|
||||
### Hook 3: UserPromptSubmit (New Session Hook)
|
||||
### Hook 2: UserPromptSubmit (New Session Hook)
|
||||
|
||||
**Purpose:** Initialize session tracking when user submits a prompt
|
||||
|
||||
@@ -251,7 +206,7 @@ VALUES (?, ?, ?, ...)
|
||||
|
||||
---
|
||||
|
||||
### Hook 4: PostToolUse (Save Observation Hook)
|
||||
### Hook 3: PostToolUse (Save Observation Hook)
|
||||
|
||||
**Purpose:** Capture tool execution observations for later processing
|
||||
|
||||
@@ -312,7 +267,7 @@ VALUES (?, ?, ?, ?, ...)
|
||||
|
||||
---
|
||||
|
||||
### Hook 5: Stop Hook (Summary Generation)
|
||||
### Hook 4: Stop Hook (Summary Generation)
|
||||
|
||||
**Purpose:** Generate AI-powered session summaries during the session
|
||||
|
||||
@@ -367,7 +322,7 @@ VALUES (?, ?, ?, ?, ...)
|
||||
|
||||
---
|
||||
|
||||
### Hook 6: SessionEnd (Cleanup Hook)
|
||||
### Hook 5: SessionEnd (Cleanup Hook)
|
||||
|
||||
**Purpose:** Mark sessions as completed when they end
|
||||
|
||||
@@ -474,14 +429,18 @@ sequenceDiagram
|
||||
|
||||
| Event | Timing | Blocking | Timeout | Output Handling |
|
||||
|-------|--------|----------|---------|-----------------|
|
||||
| **SessionStart (smart-install)** | Before session | No | 300s | stderr (info) |
|
||||
| **SessionStart (context)** | Before session | No | 300s | stdout → context |
|
||||
| **SessionStart (user-message)** | Before session | No | 10s | stderr (info) |
|
||||
| **UserPromptSubmit** | Before processing | No | 120s | stdout → context |
|
||||
| **SessionStart (smart-install)** | Before session | No | 300s | stderr (log only) |
|
||||
| **SessionStart (worker-start)** | Before session | No | 60s | stderr (log only) |
|
||||
| **SessionStart (context)** | Before session | No | 60s | JSON → additionalContext (silent) |
|
||||
| **UserPromptSubmit** | Before processing | No | 60s | stdout → context |
|
||||
| **PostToolUse** | After tool | No | 120s | Transcript only |
|
||||
| **Summary** | Worker triggered | No | 120s | Database |
|
||||
| **SessionEnd** | On exit | No | 120s | Log only |
|
||||
|
||||
<Note>
|
||||
As of Claude Code 2.1.0 (ultrathink update), SessionStart hooks no longer display user-visible messages. Context is silently injected via `hookSpecificOutput.additionalContext`.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## The Worker Service Architecture
|
||||
|
||||
@@ -22,6 +22,10 @@ That's it! The plugin will automatically:
|
||||
|
||||
Start a new Claude Code session and you'll see context from previous sessions automatically loaded.
|
||||
|
||||
> **Important:** Claude-Mem is published on npm, but running `npm install -g claude-mem` installs the
|
||||
> **SDK/library only**. It does **not** register plugin hooks or start the worker service.
|
||||
> To use Claude-Mem as a persistent memory plugin, always install via the `/plugin` commands above.
|
||||
|
||||
## System Requirements
|
||||
|
||||
- **Node.js**: 18.0.0 or higher
|
||||
|
||||
@@ -23,15 +23,16 @@ Restart Claude Code. Context from previous sessions will automatically appear in
|
||||
## Key Features
|
||||
|
||||
- 🧠 **Persistent Memory** - Context survives across sessions
|
||||
- 🌐 **Multilingual Modes** - Supports 10+ languages (Spanish, Chinese, French, etc.)
|
||||
- 🎭 **Mode System** - Switch between workflows (Code, Email Investigation)
|
||||
- 🔍 **mem-search Skill** - Query your project history with natural language (~2,250 token savings)
|
||||
- 📁 **Folder Context Files** - Auto-generated `CLAUDE.md` in project folders with activity timelines
|
||||
- 🌐 **Multilingual Modes** - Supports 28 languages (Spanish, Chinese, French, Japanese, etc.)
|
||||
- 🎭 **Mode System** - Switch between workflows (Code, Email Investigation, Chill)
|
||||
- 🔍 **MCP Search Tools** - Query your project history with natural language
|
||||
- 🌐 **Web Viewer UI** - Real-time memory stream visualization at http://localhost:37777
|
||||
- 🔒 **Privacy Control** - Use `<private>` tags to exclude sensitive content from storage
|
||||
- ⚙️ **Context Configuration** - Fine-grained control over what context gets injected
|
||||
- 🤖 **Automatic Operation** - No manual intervention required
|
||||
- 📊 **FTS5 Search** - Fast full-text search across observations
|
||||
- 🔗 **Citations** - Reference past observations with IDs (access via http://localhost:37777/api/observation/{id} or view all in the web viewer at http://localhost:37777)
|
||||
- 🔗 **Citations** - Reference past observations with IDs
|
||||
|
||||
## How It Works
|
||||
|
||||
@@ -58,11 +59,11 @@ Restart Claude Code. Context from previous sessions will automatically appear in
|
||||
```
|
||||
|
||||
**Core Components:**
|
||||
1. **5 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 hook scripts)
|
||||
1. **4 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop
|
||||
2. **Smart Install** - Cached dependency checker (pre-hook script)
|
||||
3. **Worker Service** - HTTP API on port 37777 managed by Bun
|
||||
4. **SQLite Database** - Stores sessions, observations, summaries with FTS5 search
|
||||
5. **mem-search Skill** - Query historical context with natural language
|
||||
5. **MCP Search Tools** - Query historical context with natural language
|
||||
6. **Web Viewer UI** - Real-time visualization with SSE and infinite scroll
|
||||
|
||||
See [Architecture Overview](architecture/overview) for details.
|
||||
@@ -76,21 +77,23 @@ See [Architecture Overview](architecture/overview) for details.
|
||||
|
||||
## What's New
|
||||
|
||||
**v9.0.0 - Live Context:**
|
||||
- **Folder Context Files**: Auto-generated `CLAUDE.md` in project folders with activity timelines
|
||||
- **Worktree Support**: Unified context from parent repos and git worktrees
|
||||
- **Configurable Observation Limits**: Control how many observations appear in context
|
||||
- **Windows Fixes**: Resolved IPC detection and hook execution issues
|
||||
- **Settings Auto-Creation**: `settings.json` now auto-creates on first run
|
||||
- **MCP Tools Naming**: Updated from "mem-search skill" to "MCP tools" terminology
|
||||
|
||||
**v7.1.0 - Bun Migration:**
|
||||
- Replaced PM2 with native Bun process management
|
||||
- Switched from better-sqlite3 to bun:sqlite for faster database access
|
||||
- Automatic one-time migration on first hook trigger
|
||||
- Simplified cross-platform support
|
||||
|
||||
**v7.0.0 - Context Configuration:**
|
||||
- 11 settings for fine-grained control over context injection
|
||||
- Dual-tag privacy system (`<private>` tags)
|
||||
|
||||
**Previous Highlights:**
|
||||
- **v5.5.0**: mem-search skill with 100% effectiveness rate
|
||||
- **v5.4.0**: Skill-based search (~2,250 tokens saved per session)
|
||||
- **v5.1.0**: Web viewer UI at http://localhost:37777
|
||||
|
||||
## Next Steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
@@ -100,8 +103,8 @@ See [Architecture Overview](architecture/overview) for details.
|
||||
<Card title="Getting Started" icon="rocket" href="/usage/getting-started">
|
||||
Learn how Claude-Mem works automatically
|
||||
</Card>
|
||||
<Card title="Architecture" icon="sitemap" href="/architecture/overview">
|
||||
System components & data flow
|
||||
<Card title="Folder Context" icon="folder-open" href="/usage/folder-context">
|
||||
Auto-generated folder CLAUDE.md files
|
||||
</Card>
|
||||
<Card title="Search Tools" icon="magnifying-glass" href="/usage/search-tools">
|
||||
Query your project history
|
||||
|
||||
@@ -65,6 +65,7 @@ Inherits all behavior from Code Mode but instructs Claude to generate **all** me
|
||||
| **Hindi** | `code--hi` | हिन्दी |
|
||||
| **Hungarian** | `code--hu` | Magyar |
|
||||
| **Indonesian** | `code--id` | Bahasa Indonesia |
|
||||
| **Urdu** | `code--ur` | اردو |
|
||||
| **Italian** | `code--it` | Italiano |
|
||||
| **Japanese** | `code--ja` | 日本語 |
|
||||
| **Korean** | `code--ko` | 한국어 |
|
||||
|
||||
@@ -0,0 +1,385 @@
|
||||
---
|
||||
title: OpenClaw Integration
|
||||
description: Persistent memory for OpenClaw agents — observation recording, MEMORY.md live sync, and real-time observation feeds
|
||||
icon: dragon
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The OpenClaw plugin gives claude-mem persistent memory to agents running on the [OpenClaw](https://openclaw.ai) gateway. It handles three things:
|
||||
|
||||
1. **Observation recording** — Captures tool usage from OpenClaw's embedded runner and sends it to the claude-mem worker for AI processing
|
||||
2. **MEMORY.md live sync** — Writes a continuously-updated timeline to each agent's workspace so agents always have context from previous sessions
|
||||
3. **Observation feed** — Streams new observations to messaging channels (Telegram, Discord, Slack, etc.) in real-time via SSE
|
||||
|
||||
<Info>
|
||||
OpenClaw's embedded runner (`pi-embedded`) calls the Anthropic API directly without spawning a `claude` process, so claude-mem's standard hooks never fire. This plugin bridges that gap by using OpenClaw's event system to capture the same data.
|
||||
</Info>
|
||||
|
||||
## How It Works
|
||||
|
||||
```plaintext
|
||||
OpenClaw Gateway
|
||||
│
|
||||
├── before_agent_start ──→ Sync MEMORY.md + Init session
|
||||
├── tool_result_persist ──→ Record observation + Re-sync MEMORY.md
|
||||
├── agent_end ────────────→ Summarize + Complete session
|
||||
└── gateway_start ────────→ Reset session tracking
|
||||
│
|
||||
▼
|
||||
Claude-Mem Worker (localhost:37777)
|
||||
├── POST /api/sessions/init
|
||||
├── POST /api/sessions/observations
|
||||
├── POST /api/sessions/summarize
|
||||
├── POST /api/sessions/complete
|
||||
├── GET /api/context/inject ──→ MEMORY.md content
|
||||
└── GET /stream ─────────────→ SSE → Messaging channels
|
||||
```
|
||||
|
||||
### Event Lifecycle
|
||||
|
||||
<Steps>
|
||||
<Step title="Agent starts (before_agent_start)">
|
||||
When an OpenClaw agent starts, the plugin does two things:
|
||||
|
||||
1. **Syncs MEMORY.md** — Fetches the latest timeline from the worker's `/api/context/inject` endpoint and writes it to `MEMORY.md` in the agent's workspace directory. This gives the agent context from all previous sessions before it starts working.
|
||||
|
||||
2. **Initializes a session** — Sends the user prompt to `POST /api/sessions/init` so the worker can create a new session and start processing.
|
||||
|
||||
Short prompts (under 10 characters) skip session init but still sync MEMORY.md.
|
||||
</Step>
|
||||
<Step title="Tool use recorded (tool_result_persist)">
|
||||
Every time the agent uses a tool (Read, Write, Bash, etc.), the plugin:
|
||||
|
||||
1. **Sends the observation** to `POST /api/sessions/observations` with the tool name, input, and truncated response (max 1000 chars)
|
||||
2. **Re-syncs MEMORY.md** with the latest timeline from the worker
|
||||
|
||||
Both operations are fire-and-forget — they don't block the agent from continuing work. The MEMORY.md file gets progressively richer as the session continues.
|
||||
|
||||
Tools prefixed with `memory_` are skipped to avoid recursive recording.
|
||||
</Step>
|
||||
<Step title="Agent finishes (agent_end)">
|
||||
When the agent completes, the plugin extracts the last assistant message and sends it to `POST /api/sessions/summarize`, then calls `POST /api/sessions/complete` to close the session. Both are fire-and-forget.
|
||||
</Step>
|
||||
<Step title="Gateway restarts (gateway_start)">
|
||||
Clears all session tracking (session IDs, workspace directory mappings) so agents get fresh state after a gateway restart.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### MEMORY.md Live Sync
|
||||
|
||||
The plugin writes a `MEMORY.md` file to each agent's workspace directory containing the full timeline of observations and summaries from previous sessions. This file is updated:
|
||||
|
||||
- On every `before_agent_start` event (agent gets fresh context before starting)
|
||||
- On every `tool_result_persist` event (context stays current during the session)
|
||||
|
||||
The content comes from the worker's `GET /api/context/inject?projects=<project>` endpoint, which generates a formatted markdown timeline from the SQLite database.
|
||||
|
||||
<Info>
|
||||
MEMORY.md updates are fire-and-forget. They run in the background without blocking the agent. The file reflects whatever the worker has processed so far — it doesn't wait for the current observation to be fully processed before writing.
|
||||
</Info>
|
||||
|
||||
### Observation Feed (SSE → Messaging)
|
||||
|
||||
The plugin runs a background service that connects to the worker's SSE stream (`GET /stream`) and forwards `new_observation` events to a configured messaging channel. This lets you monitor what your agents are learning in real-time from Telegram, Discord, Slack, or any supported OpenClaw channel.
|
||||
|
||||
The SSE connection uses exponential backoff (1s → 30s) for automatic reconnection.
|
||||
|
||||
## Setting Up the Observation Feed
|
||||
|
||||
The observation feed sends a formatted message to your OpenClaw channel every time claude-mem creates a new observation. Each message includes the observation title and subtitle so you can follow along as your agents work.
|
||||
|
||||
Messages look like this in your channel:
|
||||
|
||||
```
|
||||
🧠 Claude-Mem Observation
|
||||
**Implemented retry logic for API client**
|
||||
Added exponential backoff with configurable max retries to handle transient failures
|
||||
```
|
||||
|
||||
### Step 1: Choose your channel
|
||||
|
||||
The observation feed works with any channel that your OpenClaw gateway has configured. You need two pieces of information:
|
||||
|
||||
- **Channel type** — The name of the channel plugin registered with OpenClaw (e.g., `telegram`, `discord`, `slack`, `signal`, `whatsapp`, `line`)
|
||||
- **Target ID** — The chat ID, channel ID, or user ID where messages should be sent
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Telegram" icon="telegram">
|
||||
**Channel type:** `telegram`
|
||||
|
||||
**Target ID:** Your Telegram chat ID (numeric). To find it:
|
||||
1. Message [@userinfobot](https://t.me/userinfobot) on Telegram
|
||||
2. It will reply with your chat ID (e.g., `123456789`)
|
||||
3. For group chats, the ID is negative (e.g., `-1001234567890`)
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "telegram",
|
||||
"to": "123456789"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Discord" icon="discord">
|
||||
**Channel type:** `discord`
|
||||
|
||||
**Target ID:** The Discord channel ID. To find it:
|
||||
1. Enable Developer Mode in Discord (Settings → Advanced → Developer Mode)
|
||||
2. Right-click the channel → Copy Channel ID
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "discord",
|
||||
"to": "1234567890123456789"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Slack" icon="slack">
|
||||
**Channel type:** `slack`
|
||||
|
||||
**Target ID:** The Slack channel ID (not the channel name). To find it:
|
||||
1. Open the channel in Slack
|
||||
2. Click the channel name at the top
|
||||
3. Scroll to the bottom of the channel details — the ID looks like `C01ABC2DEFG`
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "slack",
|
||||
"to": "C01ABC2DEFG"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Signal" icon="signal-messenger">
|
||||
**Channel type:** `signal`
|
||||
|
||||
**Target ID:** The Signal phone number or group ID configured in your OpenClaw gateway.
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "signal",
|
||||
"to": "+1234567890"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="WhatsApp" icon="whatsapp">
|
||||
**Channel type:** `whatsapp`
|
||||
|
||||
**Target ID:** The WhatsApp phone number or group JID configured in your OpenClaw gateway.
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "whatsapp",
|
||||
"to": "+1234567890"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="LINE" icon="line">
|
||||
**Channel type:** `line`
|
||||
|
||||
**Target ID:** The LINE user ID or group ID from the LINE Developer Console.
|
||||
|
||||
```json
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "line",
|
||||
"to": "U1234567890abcdef"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### Step 2: Add the config to your gateway
|
||||
|
||||
Add the `observationFeed` block to your claude-mem plugin config in your OpenClaw gateway configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"claude-mem": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"project": "my-project",
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "telegram",
|
||||
"to": "123456789"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Warning>
|
||||
The `channel` value must match a channel plugin that is already configured and running on your OpenClaw gateway. If the channel isn't registered, you'll see `Unknown channel type: <channel>` in the logs.
|
||||
</Warning>
|
||||
|
||||
### Step 3: Verify the connection
|
||||
|
||||
After starting the gateway, check that the feed is connected:
|
||||
|
||||
1. **Check the logs** — You should see:
|
||||
```
|
||||
[claude-mem] Observation feed starting — channel: telegram, target: 123456789
|
||||
[claude-mem] Connecting to SSE stream at http://localhost:37777/stream
|
||||
[claude-mem] Connected to SSE stream
|
||||
```
|
||||
|
||||
2. **Use the status command** — Run `/claude_mem_feed` in any OpenClaw chat to see:
|
||||
```
|
||||
Claude-Mem Observation Feed
|
||||
Enabled: yes
|
||||
Channel: telegram
|
||||
Target: 123456789
|
||||
Connection: connected
|
||||
```
|
||||
|
||||
3. **Trigger a test** — Have an agent do some work. When the worker processes the tool usage into an observation, you'll receive a message in your configured channel.
|
||||
|
||||
<Info>
|
||||
The feed only sends `new_observation` events — not raw tool usage. Observations are generated asynchronously by the worker's AI agent, so there's a 1-2 second delay between tool use and the observation message appearing in your channel.
|
||||
</Info>
|
||||
|
||||
### Troubleshooting the Feed
|
||||
|
||||
| Symptom | Cause | Fix |
|
||||
|---------|-------|-----|
|
||||
| `Connection: disconnected` | Worker not running or wrong port | Check `workerPort` config, run `npm run worker:status` |
|
||||
| `Connection: reconnecting` | Worker was running but connection dropped | The plugin auto-reconnects with backoff — wait up to 30s |
|
||||
| `Unknown channel type` in logs | Channel plugin not loaded on gateway | Verify your OpenClaw gateway has the channel plugin configured |
|
||||
| No messages appearing | Feed connected but no observations being created | Check that agents are running and the worker is processing observations |
|
||||
| `Observation feed disabled` in logs | `enabled` is `false` or missing | Set `observationFeed.enabled` to `true` |
|
||||
| `Observation feed misconfigured` in logs | Missing `channel` or `to` | Both `channel` and `to` are required |
|
||||
|
||||
## Installation
|
||||
|
||||
Run this one-liner to install everything automatically:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://install.cmem.ai/openclaw.sh | bash
|
||||
```
|
||||
|
||||
The installer handles dependency checks (Bun, uv), plugin installation, memory slot configuration, AI provider setup, worker startup, and optional observation feed configuration.
|
||||
|
||||
You can also pre-select options:
|
||||
|
||||
```bash
|
||||
# With a specific AI provider
|
||||
curl -fsSL https://install.cmem.ai/openclaw.sh | bash -s -- --provider=gemini --api-key=YOUR_KEY
|
||||
|
||||
# Fully unattended (defaults to Claude Max Plan)
|
||||
curl -fsSL https://install.cmem.ai/openclaw.sh | bash -s -- --non-interactive
|
||||
|
||||
# Upgrade existing installation
|
||||
curl -fsSL https://install.cmem.ai/openclaw.sh | bash -s -- --upgrade
|
||||
```
|
||||
|
||||
### Manual Configuration
|
||||
|
||||
Add `claude-mem` to your OpenClaw gateway's plugin configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": {
|
||||
"claude-mem": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"project": "my-project",
|
||||
"syncMemoryFile": true,
|
||||
"workerPort": 37777,
|
||||
"observationFeed": {
|
||||
"enabled": true,
|
||||
"channel": "telegram",
|
||||
"to": "your-chat-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
The claude-mem worker service must be running on the same machine as the OpenClaw gateway. The plugin communicates with it via HTTP on `localhost:37777`.
|
||||
</Note>
|
||||
|
||||
## Configuration
|
||||
|
||||
<ParamField body="project" type="string" default="openclaw">
|
||||
Project name for scoping observations in the memory database. All observations from this gateway will be stored under this project name.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="syncMemoryFile" type="boolean" default={true}>
|
||||
Enable automatic MEMORY.md sync to agent workspaces. Set to `false` if you don't want the plugin writing files to workspace directories.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="workerPort" type="number" default={37777}>
|
||||
Port for the claude-mem worker service. Override if your worker runs on a non-default port.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="observationFeed.enabled" type="boolean" default={false}>
|
||||
Enable live observation streaming to messaging channels.
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="observationFeed.channel" type="string">
|
||||
Channel type: `telegram`, `discord`, `signal`, `slack`, `whatsapp`, `line`
|
||||
</ParamField>
|
||||
|
||||
<ParamField body="observationFeed.to" type="string">
|
||||
Target chat/user/channel ID to send observations to.
|
||||
</ParamField>
|
||||
|
||||
## Commands
|
||||
|
||||
### /claude_mem_feed
|
||||
|
||||
Show or toggle the observation feed status.
|
||||
|
||||
```
|
||||
/claude_mem_feed # Show current status
|
||||
/claude_mem_feed on # Request enable
|
||||
/claude_mem_feed off # Request disable
|
||||
```
|
||||
|
||||
### /claude_mem_status
|
||||
|
||||
Check worker health and session status.
|
||||
|
||||
```
|
||||
/claude_mem_status
|
||||
```
|
||||
|
||||
Returns worker status, port, active session count, and observation feed connection state.
|
||||
|
||||
## Architecture
|
||||
|
||||
The plugin uses HTTP calls to the already-running claude-mem worker service rather than spawning subprocesses. This means:
|
||||
|
||||
- No `bun` dependency required on the gateway
|
||||
- No process spawn overhead per event
|
||||
- Uses the same worker API that Claude Code hooks use
|
||||
- All operations are non-blocking (fire-and-forget where possible)
|
||||
|
||||
### Session Tracking
|
||||
|
||||
Each OpenClaw agent session gets a unique `contentSessionId` (format: `openclaw-<sessionKey>-<timestamp>`) that maps to a claude-mem session in the worker. The plugin tracks:
|
||||
|
||||
- `sessionIds` — Maps OpenClaw session keys to content session IDs
|
||||
- `workspaceDirsBySessionKey` — Maps session keys to workspace directories so `tool_result_persist` events can sync MEMORY.md even when the event context doesn't include `workspaceDir`
|
||||
|
||||
Both maps are cleared on `gateway_start`.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Claude-mem worker service running on `localhost:37777` (or configured port)
|
||||
- OpenClaw gateway with plugin support
|
||||
- Network access between gateway and worker (localhost only)
|
||||
@@ -1,23 +1,23 @@
|
||||
---
|
||||
title: Claude Desktop Skill
|
||||
description: Use claude-mem memory search in Claude Desktop with the mem-search skill
|
||||
title: Claude Desktop MCP
|
||||
description: Use claude-mem memory search in Claude Desktop with MCP tools
|
||||
icon: desktop
|
||||
---
|
||||
|
||||
<Note>
|
||||
**Availability:** The mem-search skill works with Claude Desktop on macOS and Windows.
|
||||
**Availability:** Claude-mem MCP tools work with Claude Desktop on macOS and Windows.
|
||||
</Note>
|
||||
|
||||
## Overview
|
||||
|
||||
Claude Desktop can access your claude-mem memory database through the **mem-search** skill. This allows you to search past sessions, decisions, and observations directly from Claude Desktop conversations.
|
||||
Claude Desktop can access your claude-mem memory database through **MCP tools**. This allows you to search past sessions, decisions, and observations directly from Claude Desktop conversations.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before installing the skill, ensure:
|
||||
Before configuring MCP tools, ensure:
|
||||
|
||||
1. **claude-mem is installed** and the worker service is running
|
||||
2. **MCP server is configured** in Claude Desktop (the skill uses the `mcp-search` MCP server)
|
||||
2. **MCP server is configured** in Claude Desktop (uses the `mcp-search` MCP server)
|
||||
|
||||
### Verify Worker is Running
|
||||
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
---
|
||||
title: "Folder Context Files"
|
||||
description: "Automatic per-folder CLAUDE.md files that provide directory-level context to Claude"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Claude-mem automatically generates `CLAUDE.md` files in your project folders to provide Claude with directory-level context. These files contain a summary of recent activity in each folder, helping Claude understand what work has been done and where.
|
||||
|
||||
<Info>
|
||||
This feature is **disabled by default**. Enable it via settings if you want automatic folder-level context generation.
|
||||
</Info>
|
||||
|
||||
## How It Works
|
||||
|
||||
When you work with Claude Code in a project, claude-mem tracks which files are read and modified. After each observation is saved, it automatically:
|
||||
|
||||
1. Identifies unique folder paths from touched files
|
||||
2. Queries recent observations relevant to each folder
|
||||
3. Generates a formatted timeline of activity
|
||||
4. Writes it to `CLAUDE.md` in that folder (inside `<claude-mem-context>` tags)
|
||||
|
||||
### What Gets Generated
|
||||
|
||||
Each folder's `CLAUDE.md` contains a "Recent Activity" section showing:
|
||||
|
||||
- Observation IDs for reference
|
||||
- Timestamps of when work occurred
|
||||
- Type indicators (bug fixes, features, discoveries, etc.)
|
||||
- Brief titles describing the work
|
||||
- Estimated token counts
|
||||
|
||||
```markdown
|
||||
<claude-mem-context>
|
||||
# Recent Activity
|
||||
|
||||
<!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
|
||||
|
||||
### Jan 4, 2026
|
||||
|
||||
| ID | Time | T | Title | Read |
|
||||
|----|------|---|-------|------|
|
||||
| #1234 | 4:30 PM | 🔵 | Implemented user authentication | ~250 |
|
||||
| #1235 | " | 🔴 | Fixed login redirect bug | ~180 |
|
||||
</claude-mem-context>
|
||||
```
|
||||
|
||||
### User Content Preservation
|
||||
|
||||
The auto-generated content is wrapped in `<claude-mem-context>` tags. **Any content you write outside these tags is preserved** when the file is regenerated. This means you can:
|
||||
|
||||
- Add your own documentation above or below the generated section
|
||||
- Write folder-specific instructions for Claude
|
||||
- Include architectural notes or conventions
|
||||
|
||||
```markdown
|
||||
# Authentication Module
|
||||
|
||||
This folder contains all authentication-related code.
|
||||
Follow the established patterns for new auth providers.
|
||||
|
||||
<claude-mem-context>
|
||||
... auto-generated content ...
|
||||
</claude-mem-context>
|
||||
|
||||
## Manual Notes
|
||||
|
||||
- OAuth providers go in /providers/
|
||||
- Session handling uses Redis
|
||||
```
|
||||
|
||||
### Project Root Exclusion
|
||||
|
||||
The **project root** (folders containing a `.git` directory) is **excluded** from auto-generation. This is intentional:
|
||||
|
||||
- Root `CLAUDE.md` files typically contain project-wide instructions you've written manually
|
||||
- Auto-generating at the root could overwrite important project documentation
|
||||
- Subfolders are where folder-level context is most useful
|
||||
|
||||
<Note>
|
||||
Git submodules (which have a `.git` *file* instead of directory) are correctly detected and **not** excluded, so they receive auto-generated context.
|
||||
</Note>
|
||||
|
||||
## Configuration
|
||||
|
||||
### Enabling the Feature
|
||||
|
||||
To enable folder CLAUDE.md generation, edit your settings file:
|
||||
|
||||
**1. Open `~/.claude-mem/settings.json`**
|
||||
|
||||
**2. Add or update this setting:**
|
||||
```json
|
||||
{
|
||||
"CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED": "true"
|
||||
}
|
||||
```
|
||||
|
||||
**3. Save the file** - changes take effect immediately (no restart needed)
|
||||
|
||||
| Value | Behavior |
|
||||
|-------|----------|
|
||||
| `"false"` (default) | Folder CLAUDE.md generation disabled |
|
||||
| `"true"` | Auto-generate folder CLAUDE.md files |
|
||||
|
||||
<Tip>
|
||||
If the settings file doesn't exist, create it with just the settings you want to change. Claude-mem will use defaults for any missing settings.
|
||||
</Tip>
|
||||
|
||||
## Cleanup Mode
|
||||
|
||||
The regenerate script includes a `--clean` mode for removing auto-generated content:
|
||||
|
||||
```bash
|
||||
# Preview what would be cleaned (dry run)
|
||||
bun scripts/regenerate-claude-md.ts --clean --dry-run
|
||||
|
||||
# Actually clean files
|
||||
bun scripts/regenerate-claude-md.ts --clean
|
||||
```
|
||||
|
||||
**What cleanup does:**
|
||||
1. Finds all `CLAUDE.md` files recursively
|
||||
2. Strips `<claude-mem-context>...</claude-mem-context>` sections
|
||||
3. **Deletes** files that become empty after stripping
|
||||
4. **Preserves** files that have user content outside the tags
|
||||
|
||||
This is useful for:
|
||||
- Preparing a branch for PR (removing generated files)
|
||||
- Resetting folder context to start fresh
|
||||
- Removing context before sharing code
|
||||
|
||||
## Git Integration
|
||||
|
||||
### Should You Commit These Files?
|
||||
|
||||
This is **your choice** based on your workflow. Here are the trade-offs:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Commit Them">
|
||||
**Pros:**
|
||||
- Team members see folder-level context and recent activity
|
||||
- New contributors can understand what happened where
|
||||
- Code reviewers get additional context about changes
|
||||
- Historical record of work patterns in the repo
|
||||
|
||||
**Cons:**
|
||||
- Adds files to your repository
|
||||
- Files change frequently during development
|
||||
- May create noise in diffs and commit history
|
||||
- Different team members may generate different content
|
||||
</Tab>
|
||||
<Tab title="Gitignore Them">
|
||||
**Pros:**
|
||||
- Clean repository without generated files
|
||||
- No commit noise from auto-generated content
|
||||
- Each developer has their own local context
|
||||
- Simpler git history
|
||||
|
||||
**Cons:**
|
||||
- Team doesn't share folder context
|
||||
- Context is lost when switching machines
|
||||
- New team members don't benefit from existing context
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Gitignore Pattern
|
||||
|
||||
To exclude folder CLAUDE.md files from git:
|
||||
|
||||
```gitignore
|
||||
# Ignore auto-generated folder context files
|
||||
**/CLAUDE.md
|
||||
|
||||
# But keep the root CLAUDE.md if you want
|
||||
!CLAUDE.md
|
||||
```
|
||||
|
||||
Or to ignore all CLAUDE.md files everywhere:
|
||||
```gitignore
|
||||
**/CLAUDE.md
|
||||
```
|
||||
|
||||
### Recommended Workflows
|
||||
|
||||
**For Solo Developers:**
|
||||
- Keep them local (gitignore) for personal context
|
||||
- Or commit them if you work across multiple machines
|
||||
|
||||
**For Teams:**
|
||||
- Discuss with your team which approach works best
|
||||
- Consider committing them if onboarding is frequent
|
||||
- Use `--clean` before PRs if you prefer clean diffs
|
||||
|
||||
**Before Merging PRs:**
|
||||
```bash
|
||||
# Clean up generated files before merge
|
||||
bun scripts/regenerate-claude-md.ts --clean
|
||||
git add -A
|
||||
git commit -m "chore: clean up generated CLAUDE.md files"
|
||||
```
|
||||
|
||||
## Regenerating Context
|
||||
|
||||
To manually regenerate all folder CLAUDE.md files from the database:
|
||||
|
||||
```bash
|
||||
# Preview what would be regenerated
|
||||
bun scripts/regenerate-claude-md.ts --dry-run
|
||||
|
||||
# Regenerate all folders
|
||||
bun scripts/regenerate-claude-md.ts
|
||||
|
||||
# Regenerate for a specific project only
|
||||
bun scripts/regenerate-claude-md.ts --project=my-project
|
||||
```
|
||||
|
||||
This is useful after:
|
||||
- Importing observations from another machine
|
||||
- Database recovery
|
||||
- Wanting to refresh all folder context
|
||||
|
||||
## Worktree Support
|
||||
|
||||
**New in v9.0**: Claude-mem now supports git worktrees with unified context.
|
||||
|
||||
When you're working in a git worktree, context is automatically gathered from both:
|
||||
- The parent repository (where the worktree was created)
|
||||
- The worktree directory itself
|
||||
|
||||
This means observations about shared code are visible regardless of which worktree you're in, giving you a complete picture of recent activity across all related directories.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. When generating context, claude-mem detects if your project is a worktree
|
||||
2. It identifies the parent repository automatically
|
||||
3. Timeline queries include both locations
|
||||
4. Results are interleaved chronologically
|
||||
|
||||
<Note>
|
||||
No configuration needed - worktree detection is automatic. If you're not using worktrees, this feature has no effect.
|
||||
</Note>
|
||||
|
||||
## Technical Details
|
||||
|
||||
### File Format
|
||||
|
||||
Generated content uses a consistent markdown table format:
|
||||
|
||||
| Column | Description |
|
||||
|--------|-------------|
|
||||
| ID | Observation ID (e.g., `#1234`) or session ID (`#S123`) |
|
||||
| Time | 12-hour format with AM/PM, ditto marks (`"`) for repeated times |
|
||||
| T | Type emoji indicator |
|
||||
| Title | Brief description of the observation |
|
||||
| Read | Estimated token count (e.g., `~250`) |
|
||||
|
||||
### Type Indicators
|
||||
|
||||
| Emoji | Type |
|
||||
|-------|------|
|
||||
| 🔴 | Bug fix |
|
||||
| 🟣 | Feature |
|
||||
| 🔄 | Refactor |
|
||||
| ✅ | Change |
|
||||
| 🔵 | Discovery |
|
||||
| ⚖️ | Decision |
|
||||
| 🎯 | Session |
|
||||
| 💬 | Prompt |
|
||||
|
||||
### Atomic Writes
|
||||
|
||||
Files are written atomically using a temp file + rename pattern. This prevents partial writes if the process is interrupted.
|
||||
|
||||
### Performance
|
||||
|
||||
- Updates happen asynchronously (fire-and-forget)
|
||||
- Failures are logged but don't block the main workflow
|
||||
- Only folders with actual file activity are updated
|
||||
- Deduplication prevents redundant updates for the same folder
|
||||
@@ -39,7 +39,7 @@ Claude-mem supports Google's Gemini API as an alternative to the Claude Agent SD
|
||||
|---------|--------|---------|-------------|
|
||||
| `CLAUDE_MEM_PROVIDER` | `claude`, `gemini` | `claude` | AI provider for observation extraction |
|
||||
| `CLAUDE_MEM_GEMINI_API_KEY` | string | — | Your Gemini API key |
|
||||
| `CLAUDE_MEM_GEMINI_MODEL` | `gemini-2.5-flash-lite`, `gemini-2.5-flash`, `gemini-3-flash` | `gemini-2.5-flash-lite` | Gemini model to use |
|
||||
| `CLAUDE_MEM_GEMINI_MODEL` | `gemini-2.5-flash-lite`, `gemini-2.5-flash`, `gemini-3-flash-preview` | `gemini-2.5-flash-lite` | Gemini model to use |
|
||||
| `CLAUDE_MEM_GEMINI_BILLING_ENABLED` | `true`, `false` | `false` | Skip rate limiting if billing is enabled on Google Cloud |
|
||||
|
||||
### Using the Settings UI
|
||||
@@ -79,7 +79,7 @@ The settings file takes precedence over the environment variable.
|
||||
|-------|--------------|-------|
|
||||
| `gemini-2.5-flash-lite` | 10 | Default, recommended for free tier (highest RPM) |
|
||||
| `gemini-2.5-flash` | 5 | Higher capability, lower rate limit |
|
||||
| `gemini-3-flash` | 5 | Latest model, lower rate limit |
|
||||
| `gemini-3-flash-preview` | 5 | Latest model, lower rate limit |
|
||||
|
||||
## Provider Switching
|
||||
|
||||
@@ -139,7 +139,7 @@ Google has two rate limit tiers for free usage:
|
||||
|-------|-----|-----|
|
||||
| gemini-2.5-flash-lite | 10 | 250K |
|
||||
| gemini-2.5-flash | 5 | 250K |
|
||||
| gemini-3-flash | 5 | 250K |
|
||||
| gemini-3-flash-preview | 5 | 250K |
|
||||
|
||||
Claude-mem enforces these limits automatically with built-in delays between requests. Processing may be slower but stays within limits.
|
||||
|
||||
@@ -149,7 +149,7 @@ Claude-mem enforces these limits automatically with built-in delays between requ
|
||||
|-------|-----|-----|
|
||||
| gemini-2.5-flash-lite | 4,000 | 4M |
|
||||
| gemini-2.5-flash | 1,000 | 1M |
|
||||
| gemini-3-flash | 1,000 | 1M |
|
||||
| gemini-3-flash-preview | 1,000 | 1M |
|
||||
|
||||
<Tip>
|
||||
**Recommended**: Enable billing on your Google Cloud project to unlock much higher rate limits. You won't be charged unless you exceed the generous free quota. This allows claude-mem to process observations instantly instead of waiting between requests.
|
||||
|
||||
@@ -160,13 +160,13 @@ Context injection uses progressive disclosure for efficient token usage:
|
||||
- Shows full summary details **only if** generated after last observation
|
||||
- Token cost: ~50-200 tokens for index view
|
||||
|
||||
### Layer 2: On-Demand Details (mem-search Skill)
|
||||
### Layer 2: On-Demand Details (MCP Tools)
|
||||
- Ask naturally: "What bugs did we fix?" or "How did we implement X?"
|
||||
- Claude auto-invokes mem-search skill to fetch full details
|
||||
- Claude auto-invokes MCP search tools to fetch full details
|
||||
- Search by concept, file, type, or keyword
|
||||
- Timeline context around specific observations
|
||||
- Token cost: ~100-500 tokens per observation fetched
|
||||
- Skill uses HTTP API (v5.4.0+) for efficient retrieval
|
||||
- Uses 3-layer workflow: search → timeline → get_observations
|
||||
|
||||
### Layer 3: Perfect Recall (Code Access)
|
||||
- Read source files directly when needed
|
||||
@@ -193,9 +193,9 @@ When you use `/clear`, the session doesn't end - it continues with a new prompt
|
||||
|
||||
The `/clear` command clears the conversation context visible to Claude AND re-injects fresh context from recent sessions, while the underlying session continues tracking observations.
|
||||
|
||||
## Searching Your History (v5.4.0+)
|
||||
## Searching Your History
|
||||
|
||||
Claude-Mem uses the mem-search skill for querying your project history. Simply ask naturally:
|
||||
Claude-Mem provides MCP tools for querying your project history. Simply ask naturally:
|
||||
|
||||
```
|
||||
"What bugs did we fix last session?"
|
||||
@@ -204,9 +204,7 @@ Claude-Mem uses the mem-search skill for querying your project history. Simply a
|
||||
"Show me recent work on this project"
|
||||
```
|
||||
|
||||
Claude automatically recognizes your intent and invokes the mem-search skill, which uses HTTP API endpoints to query your memory efficiently.
|
||||
|
||||
**Token Savings**: ~2,250 tokens per session start vs previous MCP approach
|
||||
Claude automatically recognizes your intent and invokes the MCP search tools, which use a 3-layer workflow (search → timeline → get_observations) for efficient token usage.
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
# Logging Analysis and Recommendations
|
||||
|
||||
**Date**: 2026-01-04
|
||||
**Status**: CRITICAL - Current logging does not prove system correctness
|
||||
**Goal**: Enable operators to visually verify the system is working and quickly discover when it isn't
|
||||
|
||||
---
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The current logging is **noisy bullshit that doesn't cover the important parts of the system**. The logging should:
|
||||
|
||||
1. **PROVE** the system is working correctly (not just record activity)
|
||||
2. **MAKE OBVIOUS** when things break (clear error paths)
|
||||
3. **TRACE** data end-to-end through the pipeline
|
||||
|
||||
### Critical Finding: Session ID Alignment is BROKEN and UNVERIFIABLE
|
||||
|
||||
The system has **three session ID types** that must stay aligned:
|
||||
- `contentSessionId` - from Claude Code (user's session)
|
||||
- `sessionDbId` - our internal database ID (integer)
|
||||
- `memorySessionId` - from Claude SDK (enables resume)
|
||||
|
||||
**The [ALIGNMENT] logs exist because this mapping is STILL a regression bug.** The current logs show intermediate values but **don't prove correctness**.
|
||||
|
||||
---
|
||||
|
||||
## Critical System Operations
|
||||
|
||||
### 1. Session ID Mapping Chain (MOST CRITICAL)
|
||||
|
||||
```
|
||||
contentSessionId (from hook)
|
||||
→ sessionDbId (our DB lookup)
|
||||
→ memorySessionId (captured from SDK)
|
||||
```
|
||||
|
||||
**If this breaks, observations go to wrong sessions = DATA CORRUPTION**
|
||||
|
||||
**Current State:**
|
||||
| Operation | Has Logging? | Proves Correctness? |
|
||||
|-----------|-------------|---------------------|
|
||||
| Hook receives contentSessionId | YES | NO - just logs receipt |
|
||||
| DB creates/looks up sessionDbId | PARTIAL | NO - no verification |
|
||||
| SDK response gives memorySessionId | YES | NO - no DB update verification |
|
||||
| Observations stored with memorySessionId | PARTIAL | NO - doesn't show which IDs used |
|
||||
|
||||
**What's MISSING:**
|
||||
|
||||
```
|
||||
[INFO] [SESSION] SESSION_CREATED | contentSessionId=abc123 → sessionDbId=42 | isNew=true
|
||||
[INFO] [SESSION] MEMORY_ID_CAPTURED | sessionDbId=42 | memorySessionId=xyz789 | dbUpdateSuccess=true
|
||||
[INFO] [SESSION] E2E_VERIFIED | contentSessionId=abc123 → sessionDbId=42 → memorySessionId=xyz789
|
||||
```
|
||||
|
||||
### 2. Observation Storage Pipeline (CRITICAL)
|
||||
|
||||
**The pipeline:**
|
||||
```
|
||||
Hook captures tool use
|
||||
→ Worker receives observation
|
||||
→ Queued to pending_messages
|
||||
→ SDK agent claims message
|
||||
→ SDK processes → generates XML
|
||||
→ Observations parsed
|
||||
→ Stored to DB with memorySessionId
|
||||
→ Synced to Chroma
|
||||
```
|
||||
|
||||
**Current State:**
|
||||
| Operation | Has Logging? | Proves Correctness? |
|
||||
|-----------|-------------|---------------------|
|
||||
| Hook captures tool | YES | Noise - "Received hook input" |
|
||||
| Observation queued | YES | Noise - just says "queued" |
|
||||
| Message claimed from queue | NO | MISSING |
|
||||
| Observation parsed | NO | MISSING |
|
||||
| Observation stored to DB | PARTIAL | NO - doesn't show IDs used |
|
||||
| DB transaction committed | NO | MISSING |
|
||||
| Chroma sync complete | DEBUG only | Should be INFO for failures |
|
||||
|
||||
**What's MISSING:**
|
||||
|
||||
```
|
||||
[INFO] [QUEUE] CLAIMED | sessionDbId=42 | messageId=5 | type=observation | tool=Bash(npm test)
|
||||
[INFO] [DB ] STORED | sessionDbId=42 | memorySessionId=xyz789 | observations=2 | ids=[101,102]
|
||||
[INFO] [QUEUE] COMPLETED | sessionDbId=42 | messageId=5 | processingTime=1.2s
|
||||
```
|
||||
|
||||
### 3. Queue Processing (CRITICAL)
|
||||
|
||||
Messages can fail, get stuck, or be lost. Current logging doesn't show:
|
||||
- When a message is claimed
|
||||
- When a message is completed
|
||||
- When a message fails and WHY
|
||||
- Queue depth and processing latency
|
||||
|
||||
**Current State:**
|
||||
- Queue enqueue: `logger.debug` (not visible at INFO)
|
||||
- Queue claim: NO LOGGING
|
||||
- Queue completion: NO LOGGING
|
||||
- Queue failure: `logger.error` (exists but rare)
|
||||
- Recovery of stuck messages: `logger.info` (good)
|
||||
|
||||
**What's MISSING:**
|
||||
|
||||
```
|
||||
[INFO] [QUEUE] ENQUEUE | sessionDbId=42 | type=observation | queueDepth=3
|
||||
[INFO] [QUEUE] CLAIM | sessionDbId=42 | messageId=5 | waitTime=0.1s
|
||||
[INFO] [QUEUE] COMPLETE | sessionDbId=42 | messageId=5 | success=true
|
||||
[ERROR][QUEUE] FAILED | sessionDbId=42 | messageId=5 | error="SDK timeout" | willRetry=true
|
||||
```
|
||||
|
||||
### 4. Context Injection (IMPORTANT)
|
||||
|
||||
When a session starts, relevant past observations should be injected. Current logging doesn't show:
|
||||
- What context was searched for
|
||||
- What was found
|
||||
- What was injected
|
||||
|
||||
**Current State:** Effectively no logging for context injection success path.
|
||||
|
||||
---
|
||||
|
||||
## What's Currently NOISE (Should Be DEBUG or Removed)
|
||||
|
||||
### Chatty Session Init Logs (new-hook.ts)
|
||||
```typescript
|
||||
// 7 INFO logs for a single session init
|
||||
logger.info('HOOK', 'new-hook: Received hook input'); // WHO CARES
|
||||
logger.info('HOOK', 'new-hook: Calling /api/sessions/init'); // WHO CARES
|
||||
logger.info('HOOK', 'new-hook: Received from /api/sessions/init'); // WHO CARES
|
||||
logger.info('HOOK', 'new-hook: Session N, prompt #M'); // CONSOLIDATE INTO ONE
|
||||
logger.info('HOOK', 'new-hook: Calling /sessions/{id}/init'); // WHO CARES
|
||||
```
|
||||
|
||||
**Should be ONE log:** `SESSION_INIT | sessionDbId=42 | promptNumber=1 | project=foo`
|
||||
|
||||
### Chatty SessionManager Logs
|
||||
```typescript
|
||||
logger.info('SESSION', 'initializeSession called'); // WHO CARES
|
||||
logger.info('SESSION', 'Returning cached session'); // DEBUG
|
||||
logger.info('SESSION', 'Fetched session from database'); // DEBUG
|
||||
logger.info('SESSION', 'Creating new session object'); // DEBUG
|
||||
logger.info('SESSION', 'Session initialized'); // GOOD - KEEP
|
||||
logger.info('SESSION', 'Observation queued'); // DEBUG - happens constantly
|
||||
logger.info('SESSION', 'Summarize queued'); // DEBUG - happens constantly
|
||||
```
|
||||
|
||||
### Chatty Chroma Backfill Logs
|
||||
```typescript
|
||||
// Logs EVERY batch at INFO - should be DEBUG for progress
|
||||
logger.info('CHROMA_SYNC', 'Backfill progress', { processed, remaining }); // DEBUG
|
||||
```
|
||||
|
||||
**Should be START and END only at INFO level.**
|
||||
|
||||
### Duplicate Migration Logs
|
||||
Both `SessionStore.ts` and `migrations/runner.ts` have ~25 identical log statements. **DEDUPLICATE.**
|
||||
|
||||
---
|
||||
|
||||
## [ALIGNMENT] Logs: The Problem
|
||||
|
||||
The [ALIGNMENT] logs were added to debug session ID issues. They're in the RIGHT places but they **don't prove anything**:
|
||||
|
||||
```typescript
|
||||
// Current - shows values but doesn't verify
|
||||
logger.info('SDK', `[ALIGNMENT] Resume Decision | contentSessionId=${...} | memorySessionId=${...}`);
|
||||
|
||||
// What's needed - proves correctness
|
||||
logger.info('SDK', `[ALIGNMENT] VERIFIED | contentSessionId=${...} → sessionDbId=${...} → memorySessionId=${...} | dbMatch=true | resumeValid=true`);
|
||||
```
|
||||
|
||||
**Current problems:**
|
||||
1. Log values without validation
|
||||
2. Don't show if DB operations succeeded
|
||||
3. Don't trace end-to-end
|
||||
4. Mixed in with noise - hard to see
|
||||
|
||||
**What they should do:**
|
||||
1. Log the mapping chain ONCE with verification
|
||||
2. Show DB operation success/failure
|
||||
3. Provide clear end-to-end trace
|
||||
4. Stand out from noise with consistent prefix
|
||||
|
||||
---
|
||||
|
||||
## Proposed Logging Architecture
|
||||
|
||||
### Log Levels by Purpose
|
||||
|
||||
| Level | Purpose | Examples |
|
||||
|-------|---------|----------|
|
||||
| ERROR | Something FAILED | DB write failed, SDK crashed, queue overflow |
|
||||
| WARN | Something UNEXPECTED but handled | Fallback used, retry needed, timeout |
|
||||
| INFO | KEY OPERATIONS completed | Session created, observation stored, queue processed |
|
||||
| DEBUG | Detailed tracing | Cache hits, intermediate states, parsing details |
|
||||
|
||||
### Critical Path Logging (Must be INFO)
|
||||
|
||||
#### Session Lifecycle
|
||||
```
|
||||
[INFO] [SESSION] CREATED | contentSessionId=abc → sessionDbId=42 | project=foo
|
||||
[INFO] [SESSION] MEMORY_ID_CAPTURED | sessionDbId=42 → memorySessionId=xyz | dbUpdated=true
|
||||
[INFO] [SESSION] VERIFIED | chain: abc→42→xyz | valid=true
|
||||
[INFO] [SESSION] COMPLETED | sessionDbId=42 | duration=45s | observations=12 | summaries=1
|
||||
```
|
||||
|
||||
#### Observation Pipeline
|
||||
```
|
||||
[INFO] [QUEUE] ENQUEUED | sessionDbId=42 | type=observation | tool=Bash(npm test) | depth=1
|
||||
[INFO] [QUEUE] CLAIMED | sessionDbId=42 | messageId=5 | waitTime=0.1s
|
||||
[INFO] [DB ] STORED | sessionDbId=42 | memorySessionId=xyz | obsIds=[101,102] | txnCommit=true
|
||||
[INFO] [QUEUE] COMPLETED | sessionDbId=42 | messageId=5 | duration=1.2s
|
||||
```
|
||||
|
||||
#### Error Conditions
|
||||
```
|
||||
[ERROR] [SESSION] MEMORY_ID_MISMATCH | expected=xyz | got=abc | sessionDbId=42
|
||||
[ERROR] [DB ] STORE_FAILED | sessionDbId=42 | error="FK constraint" | observations=2
|
||||
[ERROR] [QUEUE ] STUCK | sessionDbId=42 | stuckFor=5min | action=marking_failed
|
||||
[ERROR] [SDK ] CRASHED | sessionDbId=42 | error="Claude process died" | pendingWork=3
|
||||
```
|
||||
|
||||
### Health Dashboard Output
|
||||
|
||||
After fixes, a healthy session should produce:
|
||||
```
|
||||
[INFO] [SESSION] CREATED | contentSessionId=abc → sessionDbId=42
|
||||
[INFO] [SESSION] GENERATOR_STARTED | sessionDbId=42 | provider=claude-sdk
|
||||
[INFO] [QUEUE ] CLAIMED | sessionDbId=42 | messageId=1 | type=observation
|
||||
[INFO] [SESSION] MEMORY_ID_CAPTURED | sessionDbId=42 → memorySessionId=xyz
|
||||
[INFO] [DB ] STORED | sessionDbId=42 | memorySessionId=xyz | obsIds=[1]
|
||||
[INFO] [QUEUE ] COMPLETED | sessionDbId=42 | messageId=1
|
||||
... (more observations)
|
||||
[INFO] [QUEUE ] CLAIMED | sessionDbId=42 | messageId=5 | type=summarize
|
||||
[INFO] [DB ] STORED | sessionDbId=42 | summaryId=1
|
||||
[INFO] [QUEUE ] COMPLETED | sessionDbId=42 | messageId=5
|
||||
[INFO] [SESSION] COMPLETED | sessionDbId=42 | duration=45s | observations=12
|
||||
```
|
||||
|
||||
An UNHEALTHY session should make problems OBVIOUS:
|
||||
```
|
||||
[INFO] [SESSION] CREATED | contentSessionId=abc → sessionDbId=42
|
||||
[INFO] [SESSION] GENERATOR_STARTED | sessionDbId=42 | provider=claude-sdk
|
||||
[ERROR] [SESSION] MEMORY_ID_NOT_CAPTURED | sessionDbId=42 | waited=30s
|
||||
[ERROR] [DB ] STORE_FAILED | sessionDbId=42 | error="memorySessionId is null"
|
||||
[WARN ] [QUEUE ] STUCK | sessionDbId=42 | messageId=1 | age=60s | action=retry
|
||||
[ERROR] [SESSION] GENERATOR_CRASHED | sessionDbId=42 | error="SDK timeout"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Priorities
|
||||
|
||||
### P0: Fix Critical Missing Logs (Session Alignment)
|
||||
|
||||
1. **ResponseProcessor.ts** - Add logging BEFORE storeObservations:
|
||||
```typescript
|
||||
logger.info('DB', 'STORING | sessionDbId=... | memorySessionId=... | count=...');
|
||||
```
|
||||
|
||||
2. **SDKAgent.ts** - Verify DB update after memorySessionId capture:
|
||||
```typescript
|
||||
const updated = store.updateMemorySessionId(sessionDbId, memorySessionId);
|
||||
logger.info('SESSION', `MEMORY_ID_CAPTURED | sessionDbId=${...} | memorySessionId=${...} | dbUpdated=${updated}`);
|
||||
```
|
||||
|
||||
3. **SessionRoutes.ts** - Log session creation with verification:
|
||||
```typescript
|
||||
logger.info('SESSION', `CREATED | contentSessionId=${...} → sessionDbId=${...} | verified=true`);
|
||||
```
|
||||
|
||||
### P1: Fix Queue Processing Logs
|
||||
|
||||
1. **SessionQueueProcessor.ts** - Add CLAIM/COMPLETE logs
|
||||
2. **PendingMessageStore.ts** - Add enqueue/dequeue logs
|
||||
|
||||
### P2: Reduce Noise
|
||||
|
||||
1. Move chatty logs to DEBUG level
|
||||
2. Deduplicate migration logs
|
||||
3. Consolidate hook init logs
|
||||
|
||||
### P3: Add Health Validation
|
||||
|
||||
1. Periodic verification log: `[INFO] [HEALTH] OK | sessions=3 | pending=0 | chroma=connected`
|
||||
2. On-demand chain verification: `[INFO] [VERIFY] contentSessionId=abc chain is VALID`
|
||||
|
||||
---
|
||||
|
||||
## Files Requiring Changes
|
||||
|
||||
| File | Priority | Changes |
|
||||
|------|----------|---------|
|
||||
| `src/services/worker/agents/ResponseProcessor.ts` | P0 | Add pre-store logging with IDs |
|
||||
| `src/services/worker/SDKAgent.ts` | P0 | Verify DB update, consolidate ALIGNMENT logs |
|
||||
| `src/services/worker/http/routes/SessionRoutes.ts` | P0 | Add session creation verification log |
|
||||
| `src/services/queue/SessionQueueProcessor.ts` | P1 | Add CLAIM/COMPLETE logs |
|
||||
| `src/services/sqlite/PendingMessageStore.ts` | P1 | Add enqueue/dequeue logs |
|
||||
| `src/services/worker/SessionManager.ts` | P2 | Move chatty logs to DEBUG |
|
||||
| `src/hooks/new-hook.ts` | P2 | Consolidate to single INFO log |
|
||||
| `src/services/sync/ChromaSync.ts` | P2 | Move progress to DEBUG, keep start/end INFO |
|
||||
| `src/services/sqlite/SessionStore.ts` | P2 | Remove duplicate migration logs |
|
||||
|
||||
---
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
After implementing changes, verify:
|
||||
|
||||
- [ ] Can trace contentSessionId → sessionDbId → memorySessionId in logs
|
||||
- [ ] Can see when observation storage succeeds/fails
|
||||
- [ ] Can see queue claim/complete for each message
|
||||
- [ ] Errors are OBVIOUS and include context for debugging
|
||||
- [ ] Noise is reduced to the point where INFO level is useful
|
||||
- [ ] A "normal" session produces ~10-15 INFO logs, not 50+
|
||||
@@ -0,0 +1,58 @@
|
||||
Brainstorming Report: CLAUDE.md Distribution Architecture
|
||||
|
||||
Problem Statement
|
||||
|
||||
The current folder-level CLAUDE.md generation creates "messy repos" with many auto-generated files. While the feature is valuable (especially for PR reviews and team visibility), the file proliferation could annoy users.
|
||||
|
||||
Solutions Explored
|
||||
|
||||
1. Shell Magic / On-Read Population
|
||||
|
||||
Explored various "magic alias" approaches where content populates dynamically on read:
|
||||
- Git smudge/clean filters - Transform at checkout, not truly on-read
|
||||
- FUSE filesystem - Virtual FS with dynamic generation, powerful but heavy
|
||||
- Named pipes (FIFOs) - Fragile, editors don't handle well
|
||||
- Symlinks to generated location - Simple but not on-demand
|
||||
|
||||
2. Command Substitution (Exciting Discovery)
|
||||
|
||||
Potential Claude Code feature request - support command substitution in context config:
|
||||
{
|
||||
"context": {
|
||||
"sources": [
|
||||
{ "command": "claude-mem live-context ${CWD}" }
|
||||
]
|
||||
}
|
||||
}
|
||||
Or folder-level .claude-context files containing just:
|
||||
exec: claude-mem live-context .
|
||||
Benefits: Zero files, pure dynamic context, no staleness, no merge conflicts ever.
|
||||
|
||||
3. Ephemeral + Smart Push Architecture (Recommended)
|
||||
|
||||
Phase 1: Ephemeral Local
|
||||
- Gitignore **/CLAUDE.md (keep root CLAUDE.md for user instructions)
|
||||
- Timeline data in separate file: claude-mem-timeline.csv
|
||||
- Generated fresh on SessionStart
|
||||
- Block Claude from reading timeline file via .claude/settings.local.json: "ignorePaths": ["claude-mem-timeline.csv"]
|
||||
- Prevents duplication (data already injected via context hook)
|
||||
|
||||
Phase 2: Smart Push Timeline
|
||||
- Pre-push hook generates timeline from last commit to now
|
||||
- Writes claude-mem-timeline.csv and includes in push
|
||||
- Reviewers, CI/CD Claude agents, and team members see what happened
|
||||
- Clean separation: CLAUDE.md = human instructions, timeline.csv = machine context
|
||||
|
||||
Phase 3: Team Sync (Pro Feature)
|
||||
- Post-pull hook: claude-mem sync --from-timeline
|
||||
- Parses timeline files, validates against local DB
|
||||
- Imports missing observations with provenance tracking
|
||||
- Conflict resolution for overlapping work
|
||||
- Monetization opportunity: Team sync as paid feature
|
||||
|
||||
Key Insight: Clean Separation
|
||||
|
||||
- CLAUDE.md = User-authored project instructions (Claude SHOULD read)
|
||||
- claude-mem-timeline.csv = Machine-generated context sync (blocked from reading, already injected)
|
||||
|
||||
No collision between human documentation and machine context.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Context Hook Investigation Report
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Branch:** `feature/no-more-hook-files`
|
||||
**Status:** Partial fix committed, additional issues identified
|
||||
|
||||
## Problem
|
||||
|
||||
User reported no startup context appearing when testing the new unified CLI hook architecture.
|
||||
|
||||
## Root Cause Identified
|
||||
|
||||
**SessionStart hooks don't receive stdin data from Claude Code.**
|
||||
|
||||
The unified CLI architecture assumed all hooks receive stdin JSON data. When `readJsonFromStdin()` returns `undefined` for SessionStart, the platform adapters crashed:
|
||||
|
||||
```
|
||||
TypeError: undefined is not an object (evaluating 'e.session_id')
|
||||
```
|
||||
|
||||
**Location:** `src/cli/adapters/claude-code.ts:6` and `src/cli/adapters/cursor.ts:7`
|
||||
|
||||
The adapters did `const r = raw as any;` then accessed `r.session_id`, which fails when `raw` is `undefined`.
|
||||
|
||||
## Fix Applied
|
||||
|
||||
Changed both adapters to handle undefined input:
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
const r = raw as any;
|
||||
|
||||
// After
|
||||
const r = (raw ?? {}) as any;
|
||||
```
|
||||
|
||||
**Commit:** `78c2a0ef` - Pushed to `feature/no-more-hook-files`
|
||||
|
||||
## Additional Issue Discovered (Not Yet Fixed)
|
||||
|
||||
There's a **path mismatch** in the hooks.json that may cause issues:
|
||||
|
||||
- hooks.json references: `${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs`
|
||||
- Actual file location: `${CLAUDE_PLUGIN_ROOT}/plugin/scripts/worker-service.cjs`
|
||||
|
||||
The marketplace sync copies the whole repo structure, so files end up in a `plugin/` subdirectory. Need to verify what `CLAUDE_PLUGIN_ROOT` resolves to and whether the paths are correct.
|
||||
|
||||
## Verification Needed
|
||||
|
||||
1. Start a new Claude Code session and verify context appears
|
||||
2. Check that `CLAUDE_PLUGIN_ROOT` points to correct directory
|
||||
3. Verify hooks.json paths match actual file locations
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `src/cli/adapters/claude-code.ts` - Added null coalescing for stdin
|
||||
- `src/cli/adapters/cursor.ts` - Added null coalescing for stdin
|
||||
- `plugin/scripts/worker-service.cjs` - Rebuilt with fix
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Test the fix in a live Claude Code session
|
||||
2. Investigate the `CLAUDE_PLUGIN_ROOT` path resolution
|
||||
3. Fix paths in hooks.json if needed
|
||||
@@ -0,0 +1,248 @@
|
||||
# Issue #543 Analysis: /claude-mem Slash Command Not Available Despite Installation
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Version Analyzed:** 8.5.9
|
||||
**Status:** Expected Behavior - No such command exists
|
||||
**Related Issues:** #557 (if it exists), Windows initialization issues
|
||||
|
||||
## Issue Summary
|
||||
|
||||
A user reports that the `/claude-mem diagnostics` command returns "Unknown slash command: claude-mem" after installing claude-mem v8.5.9 on Windows.
|
||||
|
||||
### Reported Environment
|
||||
- Claude-mem version: 8.5.9
|
||||
- Claude Code version: 2.0.76
|
||||
- Node.js version: v22.21.0
|
||||
- Bun version: 1.3.5
|
||||
- OS: Windows 10.0.26200.7462 (x64)
|
||||
|
||||
### Reported Plugin Status
|
||||
- Worker Running: No
|
||||
- Database Exists: Yes (4.00 KB - minimal/empty database)
|
||||
- Settings Exist: No
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Finding 1: No `/claude-mem` Slash Command Exists
|
||||
|
||||
**Critical Discovery**: The `/claude-mem diagnostics` command does not exist in claude-mem. After extensive codebase analysis:
|
||||
|
||||
1. **No slash command registration found**: The `plugin/commands/` directory is empty. Claude-mem does not register any slash commands.
|
||||
|
||||
2. **Skills, not commands**: Claude-mem uses Claude Code's **skill system**, not the command system. Skills are defined in `plugin/skills/`:
|
||||
- `mem-search/` - Memory search functionality
|
||||
- `troubleshoot/` - Troubleshooting functionality
|
||||
- `search/` - Search operations
|
||||
- `claude-mem-settings/` - Settings management
|
||||
|
||||
3. **Empty skill directories**: All skill directories currently contain only empty subdirectories (`operations/`, `principles/`) with no SKILL.md files present in the built plugin. This suggests either:
|
||||
- Skills are dynamically loaded from the worker service
|
||||
- A build issue where skill files are not being bundled
|
||||
- Skills were removed or relocated in a recent refactor
|
||||
|
||||
### Finding 2: How Troubleshooting Actually Works
|
||||
|
||||
According to the documentation (`docs/public/troubleshooting.mdx`):
|
||||
|
||||
> "Describe any issues you're experiencing to Claude, and the troubleshoot skill will automatically activate to provide diagnosis and fixes."
|
||||
|
||||
The troubleshoot skill is designed to be **invoked naturally** - users describe their problem to Claude, and the skill auto-invokes. There is no `/claude-mem diagnostics` command.
|
||||
|
||||
### Finding 3: Settings.json Creation Flow
|
||||
|
||||
The `settings.json` file is **not created during installation**. It is created:
|
||||
|
||||
1. **On first worker API call**: The `ensureSettingsFile()` method in `SettingsRoutes.ts` (lines 400-413) creates the file with defaults when the settings API is first accessed.
|
||||
|
||||
2. **Worker must be running**: Since settings creation is triggered by API calls, the worker service must be running for settings to be created.
|
||||
|
||||
3. **Lazy initialization pattern**: This is intentional - settings are created on-demand with sensible defaults rather than during installation.
|
||||
|
||||
### Finding 4: Worker Service Not Running
|
||||
|
||||
The user reports "Worker Running: No". This is the core issue because:
|
||||
|
||||
1. **Worker auto-start on SessionStart**: The `hooks.json` shows the worker starts via:
|
||||
```json
|
||||
{
|
||||
"type": "command",
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start",
|
||||
"timeout": 60
|
||||
}
|
||||
```
|
||||
|
||||
2. **Smart-install runs first**: Before worker start, `smart-install.js` runs to ensure Bun and uv are installed.
|
||||
|
||||
3. **Windows-specific issues**: The user is on Windows, which has known issues:
|
||||
- PowerShell escaping problems in `cleanupOrphanedProcesses()` (Issue #517)
|
||||
- PATH issues with freshly installed Bun
|
||||
- Process spawning differences
|
||||
|
||||
### Finding 5: Database Size Indicates No Data
|
||||
|
||||
The database is 4.00 KB, which is essentially an empty schema:
|
||||
- No observations recorded
|
||||
- No sessions created
|
||||
- Hooks may not have executed successfully
|
||||
|
||||
## Initialization Flow Analysis
|
||||
|
||||
```
|
||||
Installation
|
||||
|
|
||||
v
|
||||
First Session Start
|
||||
|
|
||||
+---> smart-install.js (ensure Bun + uv)
|
||||
| |
|
||||
| +---> May fail silently on Windows (PATH issues)
|
||||
|
|
||||
+---> worker-service.cjs start
|
||||
| |
|
||||
| +---> Likely failing (worker not running)
|
||||
|
|
||||
+---> context-hook.js (requires worker)
|
||||
| |
|
||||
| +---> Fails or returns empty (no worker)
|
||||
|
|
||||
+---> user-message-hook.js
|
||||
|
|
||||
+---> No context injected
|
||||
```
|
||||
|
||||
## Why Skills Directories Are Empty
|
||||
|
||||
After investigation, the skill directories in `plugin/skills/` are scaffolding structures but appear to have no SKILL.md files in the built plugin. The actual skill functionality may be:
|
||||
|
||||
1. **Served via HTTP API**: The Server.ts shows an `/api/instructions` endpoint that loads SKILL.md sections on-demand from `../skills/mem-search/`
|
||||
2. **Built differently**: The skills may be bundled into the worker service rather than standalone files
|
||||
3. **Documentation discrepancy**: The README and docs reference skills that may work differently than traditional Claude Code skill files
|
||||
|
||||
## Proposed Diagnosis
|
||||
|
||||
The user's issue is **not** that `/claude-mem diagnostics` doesn't work - that command never existed. The actual issues are:
|
||||
|
||||
1. **Misunderstanding of troubleshoot functionality**: The user expects a slash command but should describe issues naturally to Claude.
|
||||
|
||||
2. **Worker service failed to start**: Root cause for:
|
||||
- No settings.json created
|
||||
- Empty database (no observations)
|
||||
- No context injection working
|
||||
|
||||
3. **Possible Windows initialization failures**:
|
||||
- Bun may not be in PATH after smart-install
|
||||
- PowerShell execution policy issues
|
||||
- Worker spawn failures
|
||||
|
||||
## Recommended User Resolution
|
||||
|
||||
### Step 1: Verify Bun Installation
|
||||
```powershell
|
||||
bun --version
|
||||
```
|
||||
If not found, manually install:
|
||||
```powershell
|
||||
powershell -c "irm bun.sh/install.ps1 | iex"
|
||||
```
|
||||
Then restart terminal.
|
||||
|
||||
### Step 2: Manually Start Worker
|
||||
```powershell
|
||||
cd ~/.claude/plugins/marketplaces/thedotmack
|
||||
bun plugin/scripts/worker-service.cjs start
|
||||
```
|
||||
|
||||
### Step 3: Verify Worker Health
|
||||
```powershell
|
||||
curl http://localhost:37777/health
|
||||
```
|
||||
|
||||
### Step 4: Create Settings Manually (if needed)
|
||||
```powershell
|
||||
curl http://localhost:37777/api/settings
|
||||
```
|
||||
This will create `~/.claude-mem/settings.json` with defaults.
|
||||
|
||||
### Step 5: For Diagnostics - Natural Language
|
||||
Instead of `/claude-mem diagnostics`, describe the issue to Claude:
|
||||
> "I'm having issues with claude-mem. Can you help troubleshoot?"
|
||||
|
||||
The troubleshoot skill should auto-invoke if the worker is running.
|
||||
|
||||
## Proposed Code Improvements
|
||||
|
||||
### 1. Add Diagnostic Slash Command
|
||||
|
||||
Create a `/claude-mem` command for diagnostics. File: `plugin/commands/claude-mem.json`:
|
||||
```json
|
||||
{
|
||||
"name": "claude-mem",
|
||||
"description": "Claude-mem diagnostics and status",
|
||||
"handler": "scripts/diagnostic-command.js"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Eager Settings Creation
|
||||
|
||||
Modify `smart-install.js` to create settings.json during installation:
|
||||
```javascript
|
||||
const settingsPath = join(homedir(), '.claude-mem', 'settings.json');
|
||||
if (!existsSync(settingsPath)) {
|
||||
mkdirSync(join(homedir(), '.claude-mem'), { recursive: true });
|
||||
writeFileSync(settingsPath, JSON.stringify(getDefaults(), null, 2));
|
||||
console.log('Created settings.json with defaults');
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Better Windows Error Reporting
|
||||
|
||||
Add explicit error messages when worker fails to start on Windows:
|
||||
```javascript
|
||||
if (process.platform === 'win32' && !workerStarted) {
|
||||
console.error('Worker failed to start on Windows.');
|
||||
console.error('Please run manually: bun plugin/scripts/worker-service.cjs start');
|
||||
console.error('And check: https://docs.claude-mem.ai/troubleshooting');
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Health Check Command
|
||||
|
||||
Add a simple health check that works without the worker:
|
||||
```javascript
|
||||
// plugin/scripts/health-check.js
|
||||
const http = require('http');
|
||||
http.get('http://localhost:37777/health', (res) => {
|
||||
if (res.statusCode === 200) console.log('Worker: RUNNING');
|
||||
else console.log('Worker: NOT RESPONDING');
|
||||
}).on('error', () => console.log('Worker: NOT RUNNING'));
|
||||
```
|
||||
|
||||
## Relationship to Issue #557
|
||||
|
||||
If Issue #557 relates to initialization issues, this analysis confirms:
|
||||
- Settings.json creation is lazy (requires worker)
|
||||
- Worker auto-start can fail silently on Windows
|
||||
- Users may have incomplete installations without clear error messages
|
||||
|
||||
## Files Examined
|
||||
|
||||
- `/plugin/.claude-plugin/plugin.json` - Plugin manifest (no commands)
|
||||
- `/plugin/hooks/hooks.json` - Hook definitions
|
||||
- `/plugin/scripts/smart-install.js` - Installation script
|
||||
- `/plugin/scripts/worker-service.cjs` - Worker service
|
||||
- `/src/services/worker/http/routes/SettingsRoutes.ts` - Settings creation
|
||||
- `/src/shared/SettingsDefaultsManager.ts` - Default values
|
||||
- `/src/shared/paths.ts` - Path definitions
|
||||
- `/docs/public/troubleshooting.mdx` - User documentation
|
||||
- `/docs/public/usage/getting-started.mdx` - User guide
|
||||
|
||||
## Conclusion
|
||||
|
||||
The reported issue is a **user expectation mismatch** combined with a **Windows initialization failure**:
|
||||
|
||||
1. `/claude-mem diagnostics` does not exist - users should use natural language to invoke the troubleshoot skill
|
||||
2. The worker service failed to start, causing cascading issues (no settings, no context)
|
||||
3. Documentation could be clearer about available commands vs skills
|
||||
4. Windows-specific initialization issues are a known pattern
|
||||
|
||||
The fix should include both user documentation improvements and potentially adding a `/claude-mem` diagnostic command for discoverability.
|
||||
@@ -0,0 +1,444 @@
|
||||
# Investigation Report: Issue #544 - mem-search Skill Hint Shown to Claude Code Users
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Issue:** https://github.com/thedotmack/claude-mem/issues/544
|
||||
**Author:** m.woelk (@neifgmbh)
|
||||
**Status:** Open
|
||||
|
||||
---
|
||||
|
||||
## Issue Summary
|
||||
|
||||
The context footer displayed to users includes the message:
|
||||
|
||||
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
This hint is misleading because:
|
||||
1. **For Claude Code users**: The "mem-search skill" terminology is confusing. In Claude Code, memory search is available through **MCP tools** (`search`, `timeline`, `get_observations`), not a "skill"
|
||||
2. **For all users**: The skill directories in `plugin/skills/` are empty - no SKILL.md files exist
|
||||
|
||||
A second user (@niteeshm) confirmed the issue with "+1 the mem-search skill is missing."
|
||||
|
||||
---
|
||||
|
||||
## Code Location Verification
|
||||
|
||||
### Confirmed Locations
|
||||
|
||||
The message appears in **two formatters** and is rendered via **FooterRenderer.ts**:
|
||||
|
||||
#### 1. MarkdownFormatter.ts (line 228-234)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts`
|
||||
|
||||
```typescript
|
||||
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. ColorFormatter.ts (line 225-231)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts`
|
||||
|
||||
```typescript
|
||||
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.${colors.reset}`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Additional References in Context Instructions
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/MarkdownFormatter.ts` (lines 70-79)
|
||||
|
||||
```typescript
|
||||
export function renderMarkdownContextIndex(): string[] {
|
||||
return [
|
||||
`**Context Index:** This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.`,
|
||||
'',
|
||||
`When you need implementation details, rationale, or debugging context:`,
|
||||
`- Use the mem-search skill to fetch full observations on-demand`,
|
||||
`- Critical types ( bugfix, decision) often need detailed fetching`,
|
||||
`- Trust this index over re-reading code for past decisions and learnings`,
|
||||
''
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/formatters/ColorFormatter.ts` (lines 72-81)
|
||||
|
||||
```typescript
|
||||
export function renderColorContextIndex(): string[] {
|
||||
return [
|
||||
`${colors.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${colors.reset}`,
|
||||
'',
|
||||
`${colors.dim}When you need implementation details, rationale, or debugging context:${colors.reset}`,
|
||||
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
||||
...
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Footer Rendering Logic
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/src/services/context/sections/FooterRenderer.ts`
|
||||
|
||||
```typescript
|
||||
export function renderFooter(
|
||||
economics: TokenEconomics,
|
||||
config: ContextConfig,
|
||||
useColors: boolean
|
||||
): string[] {
|
||||
// Only show footer if we have savings to display
|
||||
if (!shouldShowContextEconomics(config) || economics.totalDiscoveryTokens <= 0 || economics.savings <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (useColors) {
|
||||
return Color.renderColorFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
||||
}
|
||||
return Markdown.renderMarkdownFooter(economics.totalDiscoveryTokens, economics.totalReadTokens);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Detection Analysis
|
||||
|
||||
### Current State: No Detection Exists
|
||||
|
||||
**Finding:** Claude-mem does **NOT** currently differentiate between Claude Code and Claude Desktop environments.
|
||||
|
||||
**Evidence:**
|
||||
1. Searched entire `src/` directory for environment detection patterns:
|
||||
- `claude.?code`, `claude.?desktop`, `isClaudeCode`, `isClaudeDesktop`, `environment`
|
||||
- Found 22 files, but none contain Claude Code vs Claude Desktop detection logic
|
||||
|
||||
2. Hook input analysis (`SessionStartInput` in `context-hook.ts`):
|
||||
```typescript
|
||||
export interface SessionStartInput {
|
||||
session_id: string;
|
||||
transcript_path: string;
|
||||
cwd: string;
|
||||
hook_event_name?: string;
|
||||
}
|
||||
```
|
||||
No environment identifier is passed to hooks.
|
||||
|
||||
3. The `ContextConfig` type has no environment field:
|
||||
```typescript
|
||||
export interface ContextConfig {
|
||||
totalObservationCount: number;
|
||||
fullObservationCount: number;
|
||||
sessionCount: number;
|
||||
showReadTokens: boolean;
|
||||
showWorkTokens: boolean;
|
||||
// ... no environment field
|
||||
}
|
||||
```
|
||||
|
||||
### Why Detection Would Be Difficult
|
||||
|
||||
Claude Code and Claude Desktop both:
|
||||
- Use the same plugin system (hooks)
|
||||
- Use the same MCP server configuration
|
||||
- Receive the same hook input structure
|
||||
|
||||
**Potential Detection Methods:**
|
||||
1. **Process name/parent** - Check if running under "claude-code" or "Claude Desktop" process
|
||||
2. **Environment variables** - Claude may set different env vars (needs research)
|
||||
3. **MCP config location** - Different config paths for each client
|
||||
4. **User agent/client header** - If available in MCP protocol
|
||||
|
||||
---
|
||||
|
||||
## Skill Availability Analysis
|
||||
|
||||
### What Actually Exists
|
||||
|
||||
#### Claude Code MCP Tools (via `.mcp.json`)
|
||||
|
||||
**File:** `/Users/alexnewman/Scripts/claude-mem/plugin/.mcp.json`
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"mcp-search": {
|
||||
"type": "stdio",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/mcp-server.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Available MCP Tools** (from `mcp-server.ts`):
|
||||
1. `search` - Step 1: Search memory index
|
||||
2. `timeline` - Step 2: Get context around results
|
||||
3. `get_observations` - Step 3: Fetch full details by IDs
|
||||
4. `__IMPORTANT` - Workflow documentation
|
||||
|
||||
**These tools ARE available in Claude Code** via MCP protocol.
|
||||
|
||||
#### Claude Desktop Setup (Manual)
|
||||
|
||||
From documentation (`docs/public/usage/claude-desktop.mdx`):
|
||||
- Requires manual MCP server configuration in `claude_desktop_config.json`
|
||||
- Uses the same MCP server and tools as Claude Code
|
||||
- Documentation refers to this as the "mem-search skill"
|
||||
|
||||
#### Plugin Skills Directory (Empty)
|
||||
|
||||
**Path:** `/Users/alexnewman/Scripts/claude-mem/plugin/skills/`
|
||||
|
||||
```
|
||||
skills/
|
||||
claude-mem-settings/ (empty)
|
||||
mem-search/
|
||||
operations/ (empty)
|
||||
principles/ (empty)
|
||||
search/
|
||||
operations/ (empty)
|
||||
troubleshoot/
|
||||
operations/ (empty)
|
||||
```
|
||||
|
||||
**Finding:** All skill directories are empty - no `SKILL.md` files exist.
|
||||
|
||||
### Terminology Confusion
|
||||
|
||||
| What Users See | What Actually Exists |
|
||||
|---------------|---------------------|
|
||||
| "mem-search skill" | MCP tools (`search`, `timeline`, `get_observations`) |
|
||||
| "skill" | Empty directory structures in `plugin/skills/` |
|
||||
| "skill to fetch observations" | `get_observations` MCP tool |
|
||||
|
||||
**The "skill" terminology is a legacy artifact** from an earlier architecture. The current system uses MCP tools, not skills.
|
||||
|
||||
---
|
||||
|
||||
## Root Cause
|
||||
|
||||
1. **Legacy Terminology**: The footer message uses "skill" language from a previous architecture
|
||||
2. **Architecture Evolution**: The search system migrated from skill-based to MCP-based (documented in `search-architecture.mdx`):
|
||||
> "Skill approach... was removed in favor of streamlined MCP architecture"
|
||||
3. **Incomplete Migration**: The message text was not updated when the architecture changed
|
||||
4. **No Skill Files**: The skill directories exist but contain no SKILL.md files
|
||||
|
||||
---
|
||||
|
||||
## Proposed Fix Options
|
||||
|
||||
### Option 1: Update Message to Reference MCP Tools (Recommended)
|
||||
|
||||
**Change the message to accurately describe the MCP tools:**
|
||||
|
||||
**Before:**
|
||||
> "Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
**After:**
|
||||
> "Use MCP search tools (search, timeline, get_observations) to access memories by ID."
|
||||
|
||||
**Files to modify:**
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
||||
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
||||
|
||||
**Pros:**
|
||||
- Accurate for both Claude Code and Claude Desktop
|
||||
- No environment detection needed
|
||||
- Simple change
|
||||
|
||||
**Cons:**
|
||||
- Longer message
|
||||
- Users need to know about MCP tools
|
||||
|
||||
### Option 2: Remove the Hint Entirely
|
||||
|
||||
**Simply remove the "Use the mem-search skill..." portion of the message.**
|
||||
|
||||
**Before:**
|
||||
> "Access 5k tokens of past research & decisions for just 1,234t. Use the mem-search skill to access memories by ID instead of re-reading files."
|
||||
|
||||
**After:**
|
||||
> "Access 5k tokens of past research & decisions for just 1,234t."
|
||||
|
||||
**Files to modify:**
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts` (lines 75, 232)
|
||||
- `src/services/context/formatters/ColorFormatter.ts` (lines 77, 229)
|
||||
|
||||
**Pros:**
|
||||
- Simplest fix
|
||||
- No confusion about terminology
|
||||
- Cleaner footer
|
||||
|
||||
**Cons:**
|
||||
- Loses the helpful hint about memory search
|
||||
- Users may not know about MCP tools
|
||||
|
||||
### Option 3: Conditional Message Based on Environment Detection
|
||||
|
||||
**Implement environment detection and show different messages:**
|
||||
|
||||
```typescript
|
||||
export function renderFooter(economics: TokenEconomics, config: ContextConfig, useColors: boolean): string[] {
|
||||
const isClaudeCode = detectClaudeCodeEnvironment();
|
||||
const searchHint = isClaudeCode
|
||||
? "Use MCP search tools to access memories by ID."
|
||||
: "Use the mem-search skill to access memories by ID.";
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Files to modify:**
|
||||
- Create new utility: `src/utils/environment-detection.ts`
|
||||
- `src/services/context/sections/FooterRenderer.ts`
|
||||
- `src/services/context/formatters/MarkdownFormatter.ts`
|
||||
- `src/services/context/formatters/ColorFormatter.ts`
|
||||
|
||||
**Pros:**
|
||||
- Context-appropriate messaging
|
||||
- Maintains helpful hint
|
||||
|
||||
**Cons:**
|
||||
- Complex to implement
|
||||
- May be fragile (environment detection methods could break)
|
||||
- More maintenance burden
|
||||
- Unclear how to reliably detect environment
|
||||
|
||||
### Option 4: Implement Actual Skills for Claude Code
|
||||
|
||||
**Create SKILL.md files in `plugin/skills/mem-search/`:**
|
||||
|
||||
**Path:** `plugin/skills/mem-search/SKILL.md`
|
||||
```markdown
|
||||
---
|
||||
name: mem-search
|
||||
description: Search claude-mem memory database using MCP tools
|
||||
---
|
||||
|
||||
# Memory Search
|
||||
|
||||
Use MCP tools to search your project memory...
|
||||
```
|
||||
|
||||
**Pros:**
|
||||
- Makes the message accurate
|
||||
- Provides better user guidance
|
||||
- Consistent with skill-based architecture
|
||||
|
||||
**Cons:**
|
||||
- Skills may be deprecated in favor of MCP
|
||||
- More files to maintain
|
||||
- May confuse the architecture (skills wrapping MCP tools)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Recommendation
|
||||
|
||||
**Recommended: Option 1 (Update Message to Reference MCP Tools)**
|
||||
|
||||
### Rationale
|
||||
|
||||
1. **Accuracy**: MCP tools are the actual mechanism, not skills
|
||||
2. **Simplicity**: Single source of truth, no environment detection needed
|
||||
3. **Documentation Alignment**: Matches the architecture documentation
|
||||
4. **Low Risk**: Minimal code changes, no new systems
|
||||
|
||||
### Specific Changes
|
||||
|
||||
#### MarkdownFormatter.ts
|
||||
|
||||
**Line 75** (Context Index section):
|
||||
```typescript
|
||||
// Before:
|
||||
`- Use the mem-search skill to fetch full observations on-demand`,
|
||||
|
||||
// After:
|
||||
`- Use MCP tools (search, get_observations) to fetch full observations on-demand`,
|
||||
```
|
||||
|
||||
**Lines 228-234** (Footer):
|
||||
```typescript
|
||||
export function renderMarkdownFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
#### ColorFormatter.ts
|
||||
|
||||
**Line 77** (Context Index section):
|
||||
```typescript
|
||||
// Before:
|
||||
`${colors.dim} - Use the mem-search skill to fetch full observations on-demand${colors.reset}`,
|
||||
|
||||
// After:
|
||||
`${colors.dim} - Use MCP tools (search, get_observations) to fetch full observations on-demand${colors.reset}`,
|
||||
```
|
||||
|
||||
**Lines 225-231** (Footer):
|
||||
```typescript
|
||||
export function renderColorFooter(totalDiscoveryTokens: number, totalReadTokens: number): string[] {
|
||||
const workTokensK = Math.round(totalDiscoveryTokens / 1000);
|
||||
return [
|
||||
'',
|
||||
`${colors.dim}Access ${workTokensK}k tokens of past research & decisions for just ${totalReadTokens.toLocaleString()}t. Use MCP search tools to access memories by ID.${colors.reset}`
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
1. Rebuild plugin: `npm run build-and-sync`
|
||||
2. Restart Claude Code
|
||||
3. Verify footer message appears correctly
|
||||
4. Verify context index instructions appear correctly
|
||||
|
||||
---
|
||||
|
||||
## Additional Considerations
|
||||
|
||||
### Empty Skill Directories
|
||||
|
||||
The empty `plugin/skills/` directories should be addressed separately:
|
||||
- Either remove them (if skills are deprecated)
|
||||
- Or populate them with SKILL.md files (if skills are still supported)
|
||||
|
||||
This is a **separate issue** from the message text.
|
||||
|
||||
### Documentation Updates
|
||||
|
||||
If Option 1 is implemented, documentation should also be reviewed:
|
||||
- `docs/public/usage/claude-desktop.mdx` references "mem-search skill"
|
||||
- `README.md` mentions "Skill-Based Search"
|
||||
- Various i18n README files
|
||||
|
||||
Consider creating a follow-up issue for documentation consistency.
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
| Aspect | Finding |
|
||||
|--------|---------|
|
||||
| **Issue Valid?** | Yes - message is misleading |
|
||||
| **Location Verified?** | Yes - 4 locations in 2 formatters |
|
||||
| **Environment Detection?** | Does not exist |
|
||||
| **Skill Files?** | Empty directories, no SKILL.md |
|
||||
| **MCP Tools Available?** | Yes - in both Claude Code and Desktop |
|
||||
| **Recommended Fix** | Option 1: Update message to reference MCP tools |
|
||||
| **Complexity** | Low - 4 string changes |
|
||||
| **Risk** | Low - cosmetic text change |
|
||||
|
||||
---
|
||||
|
||||
*Report prepared for GitHub Issue #544*
|
||||
@@ -0,0 +1,241 @@
|
||||
# Issue #545: formatTool Crashes on Non-JSON Tool Input Strings
|
||||
|
||||
## Summary
|
||||
|
||||
**Issue**: `formatTool` method in `src/utils/logger.ts` crashes when `toolInput` is a string that is not valid JSON
|
||||
**Type**: Bug (Critical - Silent Data Loss)
|
||||
**Status**: Open
|
||||
**Author**: @Rob-van-B
|
||||
**Created**: January 4, 2026
|
||||
|
||||
The `formatTool` method unconditionally calls `JSON.parse()` on string inputs without error handling. When tool inputs are raw strings (not JSON), this throws an exception that propagates up the call stack, causing 400 errors for valid observation requests and silently stopping claude-mem from recording tool usage.
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Verified Issue Location
|
||||
|
||||
**File**: `/Users/alexnewman/Scripts/claude-mem/src/utils/logger.ts`
|
||||
**Line**: 139
|
||||
**Method**: `formatTool`
|
||||
|
||||
```typescript
|
||||
formatTool(toolName: string, toolInput?: any): string {
|
||||
if (!toolInput) return toolName;
|
||||
|
||||
const input = typeof toolInput === 'string' ? JSON.parse(toolInput) : toolInput;
|
||||
// ... rest of method
|
||||
}
|
||||
```
|
||||
|
||||
### The Problem
|
||||
|
||||
The code assumes that if `toolInput` is a string, it must be valid JSON. This assumption is incorrect. Tool inputs can be:
|
||||
|
||||
1. **Already-parsed objects** (no parsing needed)
|
||||
2. **JSON strings** (need parsing)
|
||||
3. **Raw strings that are not JSON** (will crash on parse)
|
||||
|
||||
When a raw string is passed (e.g., a Bash command like `ls -la`), `JSON.parse("ls -la")` throws:
|
||||
```
|
||||
SyntaxError: Unexpected token 'l', "ls -la" is not valid JSON
|
||||
```
|
||||
|
||||
### Existing Correct Pattern in Codebase
|
||||
|
||||
The issue is notable because the **correct pattern already exists** in `src/sdk/prompts.ts` (lines 96-102):
|
||||
|
||||
```typescript
|
||||
try {
|
||||
toolInput = typeof obs.tool_input === 'string' ? JSON.parse(obs.tool_input) : obs.tool_input;
|
||||
} catch (error) {
|
||||
logger.debug('SDK', 'Tool input is plain string, using as-is', {
|
||||
toolName: obs.tool_name
|
||||
}, error as Error);
|
||||
toolInput = obs.tool_input;
|
||||
}
|
||||
```
|
||||
|
||||
This demonstrates the correct defensive approach was implemented elsewhere but missed in `logger.ts`.
|
||||
|
||||
## Call Sites Affected
|
||||
|
||||
The `formatTool` method is called from 4 locations:
|
||||
|
||||
| File | Line | Context | Impact |
|
||||
|------|------|---------|--------|
|
||||
| `src/hooks/save-hook.ts` | 38 | PostToolUse hook logging | Hook crashes, observation lost |
|
||||
| `src/services/worker/http/middleware.ts` | 110 | HTTP request logging | 400 error returned to client |
|
||||
| `src/services/worker/SessionManager.ts` | 220 | Observation queue logging | Observation not queued |
|
||||
|
||||
All call sites pass `tool_input` directly from Claude Code's PostToolUse hook, which can be any type including raw strings.
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
### Severity: High
|
||||
|
||||
1. **Silent Data Loss**: Observations fail to save without user notification
|
||||
2. **No Error Visibility**: Worker runs as background process - errors go unnoticed
|
||||
3. **Intermittent Failures**: Only affects certain tool types with string inputs
|
||||
4. **Cascading Effect**: One failed observation can disrupt session tracking
|
||||
|
||||
### Affected Tool Types
|
||||
|
||||
Tools most likely to trigger this bug:
|
||||
|
||||
- **Bash**: Command strings like `git status`, `npm install`
|
||||
- **Grep**: Search patterns
|
||||
- **Glob**: File patterns like `**/*.ts`
|
||||
- **Custom MCP tools**: May pass raw strings
|
||||
|
||||
### Data Flow Path
|
||||
|
||||
```
|
||||
Claude Code
|
||||
|
|
||||
v
|
||||
PostToolUse Hook (save-hook.ts:38)
|
||||
|-- logger.formatTool() <-- CRASH HERE
|
||||
|
|
||||
v [if crash, never reaches]
|
||||
Worker HTTP Endpoint
|
||||
|-- middleware.ts:110 logger.formatTool() <-- CRASH HERE TOO
|
||||
|
|
||||
v [if crash, 400 returned]
|
||||
SessionManager
|
||||
|-- SessionManager.ts:220 logger.formatTool() <-- CRASH HERE TOO
|
||||
|
|
||||
v [if crash, not queued]
|
||||
Database
|
||||
```
|
||||
|
||||
## Recommended Fix
|
||||
|
||||
### Option 1: User's Proposed Fix (Minimal)
|
||||
|
||||
```typescript
|
||||
let input = toolInput;
|
||||
if (typeof toolInput === 'string') {
|
||||
try {
|
||||
input = JSON.parse(toolInput);
|
||||
} catch {
|
||||
input = { raw: toolInput };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Simple, encapsulates raw strings in an object
|
||||
**Cons**: Changes the shape of input for raw strings (may affect downstream logic)
|
||||
|
||||
### Option 2: Consistent with prompts.ts Pattern (Recommended)
|
||||
|
||||
```typescript
|
||||
formatTool(toolName: string, toolInput?: any): string {
|
||||
if (!toolInput) return toolName;
|
||||
|
||||
let input = toolInput;
|
||||
if (typeof toolInput === 'string') {
|
||||
try {
|
||||
input = JSON.parse(toolInput);
|
||||
} catch {
|
||||
// Input is a raw string, not JSON - use as-is
|
||||
input = toolInput;
|
||||
}
|
||||
}
|
||||
|
||||
// Bash: show full command
|
||||
if (toolName === 'Bash' && input.command) {
|
||||
return `${toolName}(${input.command})`;
|
||||
}
|
||||
|
||||
// Handle raw string inputs (e.g., from Bash commands passed as strings)
|
||||
if (typeof input === 'string') {
|
||||
return `${toolName}(${input.length > 50 ? input.slice(0, 50) + '...' : input})`;
|
||||
}
|
||||
|
||||
// ... rest of existing logic
|
||||
}
|
||||
```
|
||||
|
||||
**Pros**: Consistent with existing pattern, handles raw strings gracefully
|
||||
**Cons**: Requires additional check for string display formatting
|
||||
|
||||
### Option 3: Extract Shared Utility (Best Long-term)
|
||||
|
||||
Create a shared utility in `src/shared/json-utils.ts`:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* Safely parse JSON that might be a raw string
|
||||
* Returns the parsed object if valid JSON, otherwise the original value
|
||||
*/
|
||||
export function safeJsonParse<T>(value: T): T | object {
|
||||
if (typeof value !== 'string') return value;
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use in both `logger.ts` and `prompts.ts` for consistency.
|
||||
|
||||
## Similar Patterns to Review
|
||||
|
||||
Other `JSON.parse` calls that may need similar protection:
|
||||
|
||||
| File | Line | Current Protection |
|
||||
|------|------|-------------------|
|
||||
| `src/sdk/prompts.ts` | 97, 106 | Has try-catch |
|
||||
| `src/services/sqlite/PendingMessageStore.ts` | 373-374 | No try-catch (lower risk - DB data should be valid) |
|
||||
| `src/utils/logger.ts` | 139 | **No try-catch (BUG)** |
|
||||
|
||||
## Testing Considerations
|
||||
|
||||
### Unit Tests Needed
|
||||
|
||||
1. `formatTool` with valid JSON string input
|
||||
2. `formatTool` with object input (already parsed)
|
||||
3. `formatTool` with raw string input (the bug case)
|
||||
4. `formatTool` with null/undefined input
|
||||
5. `formatTool` with empty string input
|
||||
|
||||
### Integration Tests Needed
|
||||
|
||||
1. PostToolUse hook with Bash command string
|
||||
2. Observation storage with raw string tool input
|
||||
3. Full pipeline from hook through worker to database
|
||||
|
||||
### Test Cases
|
||||
|
||||
```typescript
|
||||
// Should handle raw string input without crashing
|
||||
expect(logger.formatTool('Bash', 'ls -la')).toBe('Bash(ls -la)');
|
||||
|
||||
// Should handle JSON string input
|
||||
expect(logger.formatTool('Read', '{"file_path": "/foo"}'))
|
||||
.toBe('Read(/foo)');
|
||||
|
||||
// Should handle object input
|
||||
expect(logger.formatTool('Read', { file_path: '/foo' }))
|
||||
.toBe('Read(/foo)');
|
||||
|
||||
// Should handle empty/null input
|
||||
expect(logger.formatTool('Bash')).toBe('Bash');
|
||||
expect(logger.formatTool('Bash', null)).toBe('Bash');
|
||||
```
|
||||
|
||||
## Complexity
|
||||
|
||||
**Low** - 30 minutes to 1 hour
|
||||
|
||||
- Single file change (`src/utils/logger.ts`)
|
||||
- Clear fix pattern exists in codebase
|
||||
- No breaking API changes
|
||||
- Unit tests straightforward
|
||||
|
||||
## References
|
||||
|
||||
- GitHub Issue: #545
|
||||
- Related file with correct pattern: `src/sdk/prompts.ts` (lines 96-102)
|
||||
- Logger source: `src/utils/logger.ts` (lines 136-197)
|
||||
@@ -0,0 +1,279 @@
|
||||
# Issue #555 Analysis: Windows Hooks Not Executing - hasIpc Always False
|
||||
|
||||
**Date:** 2026-01-05
|
||||
**Version Analyzed:** 8.5.9
|
||||
**Claude Code Version:** 2.0.76
|
||||
**Platform:** Windows 11 (Build 26100), Git Bash (MINGW64)
|
||||
**Status:** INVESTIGATION COMPLETE - Root cause identified
|
||||
|
||||
## Issue Summary
|
||||
|
||||
On Windows 11 with Git Bash, Claude-mem plugin hooks are not executing at all. While the worker service starts successfully and responds to health checks, no observations are being saved and no hook-related logs appear.
|
||||
|
||||
### Reported Symptoms
|
||||
|
||||
```json
|
||||
// /api/health
|
||||
{
|
||||
"status": "ok",
|
||||
"build": "TEST-008-wrapper-ipc",
|
||||
"managed": false,
|
||||
"hasIpc": false,
|
||||
"platform": "win32",
|
||||
"pid": 3596,
|
||||
"initialized": true,
|
||||
"mcpReady": true
|
||||
}
|
||||
|
||||
// /api/stats
|
||||
{
|
||||
"observations": 0,
|
||||
"sessions": 1
|
||||
}
|
||||
```
|
||||
|
||||
### Key Observations
|
||||
|
||||
1. Worker starts and responds correctly to HTTP requests
|
||||
2. `hasIpc` is `false` (this is **expected behavior**, not a bug)
|
||||
3. `observations` remains at `0` - no data being captured
|
||||
4. No `[HOOK]` entries in worker logs - hooks never execute
|
||||
5. This differs from issue #517 which was about PowerShell escaping
|
||||
|
||||
## Root Cause Analysis
|
||||
|
||||
### Primary Cause: Hook Commands Not Executing
|
||||
|
||||
The hooks defined in `plugin/hooks/hooks.json` are never being invoked by Claude Code on Windows.
|
||||
|
||||
### Understanding hasIpc
|
||||
|
||||
The `hasIpc` field is a **red herring** and is working as intended:
|
||||
|
||||
```typescript
|
||||
// src/services/server/Server.ts:152
|
||||
hasIpc: typeof process.send === 'function'
|
||||
```
|
||||
|
||||
This checks if the worker process was spawned with an IPC channel (via `fork()` or `spawn()` with `stdio: 'ipc'`). Plugin hooks execute as independent command-line processes, NOT as forked child processes with IPC channels. Therefore, `hasIpc: false` is the **expected, normal behavior** for all hook executions.
|
||||
|
||||
### Actual Problem: Hook Command Execution Failure
|
||||
|
||||
The hooks.json uses Unix-style environment variable syntax:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start"
|
||||
}
|
||||
```
|
||||
|
||||
**On Windows, this fails because:**
|
||||
|
||||
1. **Shell Interpreter Mismatch**: Claude Code on Windows likely uses `cmd.exe` or PowerShell to execute hook commands, not Git Bash. The `${VARIABLE}` syntax only works in Bash; cmd.exe uses `%VARIABLE%`.
|
||||
|
||||
2. **PATH Environment Differences**: The user runs Claude in Git Bash where `bun` and `node` are in PATH. However, Claude Code executes hooks in its own shell context (likely cmd.exe), which may not inherit Git Bash's PATH configuration.
|
||||
|
||||
3. **CLAUDE_PLUGIN_ROOT Resolution**: If Claude Code doesn't properly set or expand `CLAUDE_PLUGIN_ROOT` before executing the command, the entire path becomes invalid.
|
||||
|
||||
## Code Investigation Findings
|
||||
|
||||
### Affected Files
|
||||
|
||||
| File | Purpose | Issue |
|
||||
|------|---------|-------|
|
||||
| `plugin/hooks/hooks.json` | Hook command definitions | Uses `${CLAUDE_PLUGIN_ROOT}` Unix syntax |
|
||||
| `plugin/scripts/smart-install.js` | Dependency installer | Executed via hooks.json, never runs on Windows |
|
||||
| `plugin/scripts/worker-service.cjs` | Worker CLI | Executed via hooks.json, never runs on Windows |
|
||||
| `plugin/scripts/*.js` | Hook scripts | None execute because hooks.json commands fail |
|
||||
|
||||
### hooks.json Analysis
|
||||
|
||||
Current hooks.json commands:
|
||||
|
||||
```json
|
||||
{
|
||||
"SessionStart": [{
|
||||
"hooks": [
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/smart-install.js\"" },
|
||||
{ "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start" },
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/context-hook.js\"" }
|
||||
]
|
||||
}],
|
||||
"PostToolUse": [{
|
||||
"hooks": [
|
||||
{ "command": "bun \"${CLAUDE_PLUGIN_ROOT}/scripts/worker-service.cjs\" start" },
|
||||
{ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/save-hook.js\"" }
|
||||
]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
**Problems identified:**
|
||||
|
||||
1. `${CLAUDE_PLUGIN_ROOT}` - Unix variable expansion, fails in cmd.exe
|
||||
2. `bun` command - May not be in system PATH on Windows
|
||||
3. `node` command - May not be in system PATH accessible to Claude Code
|
||||
|
||||
### Worker hasIpc Usage
|
||||
|
||||
The hasIpc field is used only for admin endpoint IPC messaging, which is a separate concern from hook execution:
|
||||
|
||||
```typescript
|
||||
// src/services/server/Server.ts:209-216
|
||||
const isWindowsManaged = process.platform === 'win32' &&
|
||||
process.env.CLAUDE_MEM_MANAGED === 'true' &&
|
||||
process.send;
|
||||
|
||||
if (isWindowsManaged) {
|
||||
process.send!({ type: 'restart' });
|
||||
}
|
||||
```
|
||||
|
||||
This IPC mechanism is for managed process scenarios and is unrelated to why hooks aren't executing.
|
||||
|
||||
## Relationship to Issue #517
|
||||
|
||||
| Aspect | Issue #517 | Issue #555 |
|
||||
|--------|------------|------------|
|
||||
| **Problem** | PowerShell `$_` variable misinterpreted by Bash | Hooks not executing at all |
|
||||
| **Location** | ProcessManager.ts (worker internals) | hooks.json execution by Claude Code |
|
||||
| **Fix Applied** | Replaced PowerShell with WMIC | N/A (new issue) |
|
||||
| **Scope** | Worker process management | Claude Code hook invocation |
|
||||
|
||||
Issue #517 fixed internal worker operations (orphaned process cleanup). Issue #555 is a completely different layer - it's about Claude Code's plugin system failing to invoke hooks on Windows.
|
||||
|
||||
## Proposed Fix
|
||||
|
||||
### Option 1: Cross-Platform Wrapper Script (Recommended)
|
||||
|
||||
Create a platform-aware wrapper that handles path resolution:
|
||||
|
||||
```javascript
|
||||
// plugin/scripts/hook-runner.js
|
||||
#!/usr/bin/env node
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
// Resolve CLAUDE_PLUGIN_ROOT or compute from script location
|
||||
const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT ||
|
||||
path.dirname(__dirname);
|
||||
|
||||
const hookScript = process.argv[2];
|
||||
const hookPath = path.join(pluginRoot, 'scripts', hookScript);
|
||||
|
||||
// Execute the actual hook
|
||||
require(hookPath);
|
||||
```
|
||||
|
||||
Update hooks.json to use relative paths:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node ./scripts/hook-runner.js context-hook.js"
|
||||
}
|
||||
```
|
||||
|
||||
### Option 2: Windows-Specific hooks.json
|
||||
|
||||
Create a Windows-compatible version using `%CLAUDE_PLUGIN_ROOT%` syntax:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node \"%CLAUDE_PLUGIN_ROOT%\\scripts\\smart-install.js\""
|
||||
}
|
||||
```
|
||||
|
||||
**Drawback:** Requires maintaining two hooks.json versions or using conditional logic.
|
||||
|
||||
### Option 3: Use Absolute Paths
|
||||
|
||||
Generate hooks.json at install time with resolved absolute paths:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "node \"C:\\Users\\username\\.claude\\plugins\\marketplaces\\thedotmack\\plugin\\scripts\\smart-install.js\""
|
||||
}
|
||||
```
|
||||
|
||||
**Drawback:** Less portable, requires install-time generation.
|
||||
|
||||
### Option 4: Ensure bun/node in System PATH
|
||||
|
||||
Add installation validation to ensure `bun` and `node` are in the system-wide PATH, not just Git Bash's PATH:
|
||||
|
||||
```powershell
|
||||
# In smart-install.js for Windows
|
||||
if (IS_WINDOWS) {
|
||||
// Add to system PATH if not present
|
||||
// Or use absolute paths to node/bun executables
|
||||
}
|
||||
```
|
||||
|
||||
## Debugging Steps for Users
|
||||
|
||||
1. **Verify plugin registration:**
|
||||
```powershell
|
||||
claude /status
|
||||
```
|
||||
|
||||
2. **Check plugin installation:**
|
||||
```powershell
|
||||
dir $env:USERPROFILE\.claude\plugins\marketplaces\thedotmack\plugin\hooks
|
||||
```
|
||||
|
||||
3. **Test environment variable:**
|
||||
```powershell
|
||||
$env:CLAUDE_PLUGIN_ROOT = "$env:USERPROFILE\.claude\plugins\marketplaces\thedotmack\plugin"
|
||||
node "$env:CLAUDE_PLUGIN_ROOT\scripts\smart-install.js"
|
||||
```
|
||||
|
||||
4. **Check if node/bun are in system PATH:**
|
||||
```powershell
|
||||
where.exe node
|
||||
where.exe bun
|
||||
```
|
||||
|
||||
5. **Enable Claude Code debug logging:**
|
||||
- Check Claude Code settings for debug/verbose mode
|
||||
- Look for hook execution errors in logs
|
||||
|
||||
## Impact Assessment
|
||||
|
||||
- **Severity:** High - Complete loss of memory functionality on Windows
|
||||
- **Scope:** All Windows users, especially those using Git Bash
|
||||
- **Workaround:** None currently - hooks must execute for memory to work
|
||||
- **Affected Versions:** Likely affects 8.5.x on Windows with Claude Code 2.0.76+
|
||||
|
||||
## Recommended Actions
|
||||
|
||||
1. **Immediate:** Document the issue and potential workarounds
|
||||
2. **Short-term:** Implement Option 1 (cross-platform wrapper script)
|
||||
3. **Long-term:** Request clarification from Anthropic on Windows hook execution behavior
|
||||
4. **Testing:** Add Windows CI/CD testing for hook execution
|
||||
|
||||
## Files to Modify
|
||||
|
||||
1. `plugin/hooks/hooks.json` - Update command syntax
|
||||
2. `plugin/scripts/hook-runner.js` - New cross-platform wrapper (create)
|
||||
3. `plugin/scripts/smart-install.js` - Add PATH validation for Windows
|
||||
4. `docs/public/troubleshooting.mdx` - Document Windows hook issues
|
||||
|
||||
## Appendix: Technical Details
|
||||
|
||||
### Environment Variable Expansion by Shell
|
||||
|
||||
| Shell | Syntax | Works in hooks.json |
|
||||
|-------|--------|---------------------|
|
||||
| Bash | `${VAR}` or `$VAR` | Yes (if Bash executes) |
|
||||
| cmd.exe | `%VAR%` | Yes (if cmd executes) |
|
||||
| PowerShell | `$env:VAR` | Yes (if PS executes) |
|
||||
|
||||
### Claude Code Hook Execution Flow
|
||||
|
||||
1. Claude Code loads hooks.json from plugin directory
|
||||
2. On hook event (SessionStart, PostToolUse, etc.), executes defined commands
|
||||
3. Commands are executed via system shell (platform-dependent)
|
||||
4. Hook process receives JSON via stdin, outputs response to stdout
|
||||
5. Claude Code processes hook output
|
||||
|
||||
The failure occurs at step 3 when the shell cannot resolve the command or environment variables.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user