chat-recall 0.0.1 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/LICENSE +93 -0
  2. package/dist/auto-update.d.ts +52 -0
  3. package/dist/auto-update.d.ts.map +1 -0
  4. package/dist/auto-update.js +157 -0
  5. package/dist/auto-update.js.map +1 -0
  6. package/dist/cli.d.ts +6 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +26102 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/client-events.d.ts +11 -0
  11. package/dist/client-events.d.ts.map +1 -0
  12. package/dist/client-events.js +77 -0
  13. package/dist/client-events.js.map +1 -0
  14. package/dist/collector-migrate.d.ts +27 -0
  15. package/dist/collector-migrate.d.ts.map +1 -0
  16. package/dist/collector-migrate.js +60 -0
  17. package/dist/collector-migrate.js.map +1 -0
  18. package/dist/device-auth.d.ts +37 -0
  19. package/dist/device-auth.d.ts.map +1 -0
  20. package/dist/device-auth.js +161 -0
  21. package/dist/device-auth.js.map +1 -0
  22. package/dist/escalate.d.ts +99 -0
  23. package/dist/escalate.d.ts.map +1 -0
  24. package/dist/escalate.js +219 -0
  25. package/dist/escalate.js.map +1 -0
  26. package/dist/http.d.ts +14 -0
  27. package/dist/http.d.ts.map +1 -0
  28. package/dist/http.js +49 -0
  29. package/dist/http.js.map +1 -0
  30. package/dist/install-skills.d.ts +51 -0
  31. package/dist/install-skills.d.ts.map +1 -0
  32. package/dist/install-skills.js +223 -0
  33. package/dist/install-skills.js.map +1 -0
  34. package/dist/intent-drain.d.ts +25 -0
  35. package/dist/intent-drain.d.ts.map +1 -0
  36. package/dist/intent-drain.js +189 -0
  37. package/dist/intent-drain.js.map +1 -0
  38. package/dist/keyring.d.ts +28 -0
  39. package/dist/keyring.d.ts.map +1 -0
  40. package/dist/keyring.js +163 -0
  41. package/dist/keyring.js.map +1 -0
  42. package/dist/mcp.d.ts +8 -0
  43. package/dist/mcp.d.ts.map +1 -0
  44. package/dist/mcp.js +23665 -0
  45. package/dist/mcp.js.map +1 -0
  46. package/dist/project-tasks.d.ts +54 -0
  47. package/dist/project-tasks.d.ts.map +1 -0
  48. package/dist/project-tasks.js +204 -0
  49. package/dist/project-tasks.js.map +1 -0
  50. package/dist/repair.d.ts +73 -0
  51. package/dist/repair.d.ts.map +1 -0
  52. package/dist/repair.js +267 -0
  53. package/dist/repair.js.map +1 -0
  54. package/dist/self-restart.d.ts +91 -0
  55. package/dist/self-restart.d.ts.map +1 -0
  56. package/dist/self-restart.js +137 -0
  57. package/dist/self-restart.js.map +1 -0
  58. package/dist/service-installer.d.ts +32 -0
  59. package/dist/service-installer.d.ts.map +1 -0
  60. package/dist/service-installer.js +231 -0
  61. package/dist/service-installer.js.map +1 -0
  62. package/dist/sync-client.d.ts +234 -0
  63. package/dist/sync-client.d.ts.map +1 -0
  64. package/dist/sync-client.js +1985 -0
  65. package/dist/sync-client.js.map +1 -0
  66. package/dist/sync-ledger.d.ts +131 -0
  67. package/dist/sync-ledger.d.ts.map +1 -0
  68. package/dist/sync-ledger.js +366 -0
  69. package/dist/sync-ledger.js.map +1 -0
  70. package/dist/update-notice.d.ts +16 -0
  71. package/dist/update-notice.d.ts.map +1 -0
  72. package/dist/update-notice.js +107 -0
  73. package/dist/update-notice.js.map +1 -0
  74. package/dist/verify-deep.d.ts +79 -0
  75. package/dist/verify-deep.d.ts.map +1 -0
  76. package/dist/verify-deep.js +97 -0
  77. package/dist/verify-deep.js.map +1 -0
  78. package/dist/verify-repair.d.ts +21 -0
  79. package/dist/verify-repair.d.ts.map +1 -0
  80. package/dist/verify-repair.js +58 -0
  81. package/dist/verify-repair.js.map +1 -0
  82. package/dist/watch.js +21550 -0
  83. package/hooks/chat_recall_escalate_hook.sh +51 -0
  84. package/hooks/chat_recall_resume_hook.sh +69 -0
  85. package/hooks/chat_recall_save_hook.sh +254 -0
  86. package/hooks/chat_recall_wakeup_hook.sh +39 -0
  87. package/package.json +38 -4
  88. package/skills/chat-recall/SKILL.md +76 -0
  89. package/skills/chat-recall-changes/SKILL.md +50 -0
  90. package/skills/chat-recall-find/SKILL.md +64 -0
  91. package/skills/chat-recall-memory/SKILL.md +55 -0
  92. package/skills/chat-recall-project/SKILL.md +75 -0
  93. package/skills/chat-recall-resume/SKILL.md +62 -0
  94. package/README.md +0 -7
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env bash
2
+ # chat-recall escalate hook — fires on SessionEnd.
3
+ #
4
+ # The write half of the Context Engineering loop: the SessionStart wake-up
5
+ # hook injects prior knowledge INTO a new session; this hook escalates the
6
+ # finished session's learnings (decisions the agent announced, corrections
7
+ # the user gave, and the outcome) OUT into the temporal knowledge graph via
8
+ # `chat-recall escalate`, so the next wake-up already knows them.
9
+ #
10
+ # Runs asynchronously: the work is backgrounded and detached, so session end
11
+ # never waits on network writes. The delay gives the collector a chance to
12
+ # sync the session's final events before extraction.
13
+ #
14
+ # Always exits 0. A hook must never break session end.
15
+ #
16
+ # Configurable via env:
17
+ # CHAT_RECALL_BIN — path to the chat-recall binary (default: which chat-recall)
18
+ # CHAT_RECALL_ESCALATE_TIMEOUT — seconds before the background run gives up (default 60)
19
+ # CHAT_RECALL_ESCALATE_DELAY — seconds to wait for the final sync (default 20)
20
+
21
+ set -uo pipefail
22
+
23
+ # Claude Code passes the hook payload as JSON on stdin; cwd is the project dir.
24
+ INPUT="$(cat 2>/dev/null || true)"
25
+ CWD=""
26
+ SESSION_ID=""
27
+ if command -v jq >/dev/null 2>&1; then
28
+ CWD="$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)"
29
+ SESSION_ID="$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null || true)"
30
+ fi
31
+ [[ -z "$CWD" ]] && CWD="$PWD"
32
+
33
+ CHAT_RECALL_BIN="${CHAT_RECALL_BIN:-$(command -v chat-recall || true)}"
34
+ if [[ -z "$CHAT_RECALL_BIN" ]] || [[ ! -x "$CHAT_RECALL_BIN" ]]; then exit 0; fi
35
+
36
+ TIMEOUT="${CHAT_RECALL_ESCALATE_TIMEOUT:-60}"
37
+ DELAY="${CHAT_RECALL_ESCALATE_DELAY:-20}"
38
+
39
+ # Detach completely: no stdio ties back to the session, so Claude Code's
40
+ # hook runner returns immediately and the escalation happens in the background.
41
+ (
42
+ sleep "$DELAY"
43
+ cd "$CWD" 2>/dev/null || true
44
+ if [[ -n "$SESSION_ID" ]]; then
45
+ timeout "$TIMEOUT" "$CHAT_RECALL_BIN" escalate "$SESSION_ID" >/dev/null 2>&1 || true
46
+ else
47
+ timeout "$TIMEOUT" "$CHAT_RECALL_BIN" escalate --latest >/dev/null 2>&1 || true
48
+ fi
49
+ ) </dev/null >/dev/null 2>&1 &
50
+
51
+ exit 0
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ # chat-recall resume hint hook — fires on UserPromptSubmit.
3
+ #
4
+ # Reads the user's typed prompt from stdin (Claude Code hook input format) and,
5
+ # if it looks like a "real" task (not a slash command, not a one-word reply),
6
+ # searches chat-recall for sessions that worked on something similar. If high-
7
+ # confidence matches exist, prints a short note that gets injected into the
8
+ # session as additional context.
9
+ #
10
+ # Exit code 0 + stdout → injected as context for the assistant.
11
+ # Exit code 0 + no stdout → silent (the default when nothing useful to say).
12
+ # We never block the prompt (would be exit code 2). This is advisory only.
13
+ #
14
+ # Configurable via env:
15
+ # CHAT_RECALL_RESUME_THRESHOLD — min top score to surface (default 0.001 for FTS5)
16
+ # CHAT_RECALL_RESUME_MAX — max number of matches to mention (default 3)
17
+ # CHAT_RECALL_BIN — path to the chat-recall binary (default: which chat-recall)
18
+
19
+ set -euo pipefail
20
+
21
+ # Read the hook payload from stdin. Tolerate non-JSON or missing fields.
22
+ INPUT="$(cat)"
23
+
24
+ # Extract prompt — bail out cleanly if jq is missing or input is malformed.
25
+ if ! command -v jq >/dev/null 2>&1; then exit 0; fi
26
+ PROMPT="$(echo "$INPUT" | jq -r '.prompt // empty')"
27
+
28
+ # Skip if there's nothing useful to search on:
29
+ # - empty / very short prompts
30
+ # - slash commands (start with /)
31
+ # - replies that are just confirmations ("yes", "ok", etc.)
32
+ if [[ -z "$PROMPT" ]]; then exit 0; fi
33
+ if [[ "${#PROMPT}" -lt 20 ]]; then exit 0; fi
34
+ if [[ "$PROMPT" == /* ]]; then exit 0; fi
35
+ if [[ "$PROMPT" =~ ^(yes|no|ok|okay|sure|continue|go|next|y|n)[[:space:]\.\!\?]*$ ]]; then exit 0; fi
36
+
37
+ CHAT_RECALL_BIN="${CHAT_RECALL_BIN:-$(command -v chat-recall || true)}"
38
+ if [[ -z "$CHAT_RECALL_BIN" ]] || [[ ! -x "$CHAT_RECALL_BIN" ]]; then
39
+ # chat-recall not on PATH — install it first; nothing to do.
40
+ exit 0
41
+ fi
42
+
43
+ MAX="${CHAT_RECALL_RESUME_MAX:-3}"
44
+
45
+ # Search the index. We use the search subcommand (not MCP) because hooks need
46
+ # to be fast and synchronous. Output is plain text we'll grep for session ids.
47
+ # Cap the prompt at 400 chars to avoid blowing up FTS5 query parsing.
48
+ PROMPT_SHORT="${PROMPT:0:400}"
49
+ SEARCH_OUT="$("$CHAT_RECALL_BIN" search "$PROMPT_SHORT" --top "$MAX" 2>/dev/null || true)"
50
+
51
+ # If we got no results back, exit silently — no context to add.
52
+ if [[ -z "$SEARCH_OUT" ]] || ! echo "$SEARCH_OUT" | grep -qE 'session|score|project'; then
53
+ exit 0
54
+ fi
55
+
56
+ # Emit a compact, agent-friendly hint. The leading marker lets the assistant
57
+ # recognize the source of this context.
58
+ {
59
+ echo "<!-- chat-recall-resume-hint -->"
60
+ echo "**📚 You've worked on something similar before** — chat-recall found these sessions:"
61
+ echo
62
+ # Take the first ~15 lines of search output as the digest. The CLI already
63
+ # formats nicely; we just trim.
64
+ echo "$SEARCH_OUT" | head -n 18
65
+ echo
66
+ echo "_Use \`recall_show <session-id>\` or \`recall_smart_resume <session-id>\` to load full context if relevant._"
67
+ } || true
68
+
69
+ exit 0
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env bash
2
+ # chat-recall save hook — auto-saves memory every 15 messages
3
+ # Installed as a Claude Code hook in ~/.claude/hooks.json
4
+ #
5
+ # This hook fires every 15 messages during a session.
6
+ # It extracts key facts (decisions, topics, tools) and saves them
7
+ # so they're preserved even if the session ends unexpectedly.
8
+ #
9
+ # Setup (one-time):
10
+ # 1. Copy this file to ~/.claude/chat-recall-hooks/
11
+ # 2. Add to ~/.claude/hooks.json:
12
+ # {
13
+ # "hooks": {
14
+ # "Stop": [{"matcher": "", "hooks": [{"type": "command", "command": "/home/YOU/.claude/chat-recall-hooks/chat_recall_save_hook.sh"}]}],
15
+ # "PreCompact": [{"matcher": "", "hooks": [{"type": "command", "command": "/home/YOU/.claude/chat-recall-hooks/chat_recall_save_hook.sh --precompact"}]}]
16
+ # }
17
+ # }
18
+
19
+ set -euo pipefail
20
+
21
+ HOOKS_DIR="${HOME}/.claude/chat-recall-hooks"
22
+ MEMORY_DIR="${HOME}/.claude/chat-recall-memory"
23
+ STATE_FILE="${MEMORY_DIR}/last_save.json"
24
+ SESSION_ID=""
25
+
26
+ log() {
27
+ echo "[chat-recall-save] $(date +%H:%M:%S) $*" >&2
28
+ }
29
+
30
+ init() {
31
+ mkdir -p "${MEMORY_DIR}"
32
+ mkdir -p "${HOOKS_DIR}"
33
+ }
34
+
35
+ # Detect current session from transcript
36
+ detect_session() {
37
+ local projects_dir="${HOME}/.claude/projects"
38
+
39
+ # Find the most recently modified session file
40
+ local latest_file=""
41
+ local latest_time=0
42
+
43
+ if [[ -d "$projects_dir" ]]; then
44
+ for dir in "$projects_dir"/*/; do
45
+ if [[ -d "$dir" ]]; then
46
+ for file in "$dir"/*.jsonl; do
47
+ if [[ -f "$file" ]]; then
48
+ local mtime
49
+ mtime=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null || echo 0)
50
+ if [[ "$mtime" -gt "$latest_time" ]]; then
51
+ latest_time="$mtime"
52
+ latest_file="$file"
53
+ fi
54
+ fi
55
+ done
56
+ fi
57
+ done
58
+ fi
59
+
60
+ if [[ -n "$latest_file" && -f "$latest_file" ]]; then
61
+ SESSION_ID=$(basename "$latest_file" .jsonl)
62
+ fi
63
+ }
64
+
65
+ # Extract key facts from a session file
66
+ extract_facts() {
67
+ local session_file="$1"
68
+ local session_id="$2"
69
+
70
+ if [[ ! -f "$session_file" ]]; then
71
+ echo "{}"
72
+ return
73
+ fi
74
+
75
+ # Count messages
76
+ local msg_count
77
+ msg_count=$(wc -l < "$session_file" 2>/dev/null || echo 0)
78
+
79
+ # Extract unique tools used
80
+ local tools
81
+ tools=$(grep -o '"type":"tool_use"' "$session_file" 2>/dev/null | wc -l | tr -d ' ')
82
+
83
+ # Extract topics from first user message
84
+ local first_topic
85
+ first_topic=$(grep -m1 '"type":"user"' "$session_file" 2>/dev/null | \
86
+ sed 's/.*"text":"//' | sed 's/".*//' | head -c 200 | tr -d '\n' | tr -d '"')
87
+
88
+ # Extract decisions (heuristic)
89
+ local decisions=""
90
+ decisions=$(grep -i "decided\|chose\|going with\|recommend\|prefer" "$session_file" 2>/dev/null | \
91
+ head -3 | sed 's/.*"text":"//' | sed 's/".*//' | head -c 300 | tr -d '\n')
92
+
93
+ # Get project path
94
+ local project_path=""
95
+ for dir in "${HOME}"/.claude/projects/*/; do
96
+ if [[ -d "$dir" && -f "${dir}${session_id}.jsonl" ]]; then
97
+ project_path=$(echo "$dir" | sed "s|${HOME}/.claude/projects/||" | sed 's|/||g' | sed 's|^|/|')
98
+ project_path=$(echo "$project_path" | sed "s|-|/|g")
99
+ break
100
+ fi
101
+ done
102
+
103
+ # Output JSON
104
+ cat <<EOF
105
+ {
106
+ "session_id": "$session_id",
107
+ "project_path": "$project_path",
108
+ "message_count": $msg_count,
109
+ "tool_uses": $tools,
110
+ "first_topic": "$(echo "$first_topic" | jq -Rs '.' 2>/dev/null || echo "\"$first_topic\"")",
111
+ "decisions": "$(echo "$decisions" | jq -Rs '.' 2>/dev/null || echo "\"\"")",
112
+ "saved_at": "$(date -Iseconds)"
113
+ }
114
+ EOF
115
+ }
116
+
117
+ # Count messages in current session
118
+ count_messages() {
119
+ local session_file="$1"
120
+ if [[ ! -f "$session_file" ]]; then
121
+ echo 0
122
+ return
123
+ fi
124
+ grep -c '"type":"user"\|\|"type":"assistant"' "$session_file" 2>/dev/null || echo 0
125
+ }
126
+
127
+ # Main save logic
128
+ do_save() {
129
+ local precompact="${1:-false}"
130
+
131
+ detect_session
132
+
133
+ if [[ -z "$SESSION_ID" ]]; then
134
+ log "No active session found"
135
+ return
136
+ fi
137
+
138
+ # Find the session file
139
+ local session_file=""
140
+ for dir in "${HOME}"/.claude/projects/*/; do
141
+ if [[ -f "${dir}${SESSION_ID}.jsonl" ]]; then
142
+ session_file="${dir}${SESSION_ID}.jsonl"
143
+ break
144
+ fi
145
+ done
146
+
147
+ if [[ -z "$session_file" || ! -f "$session_file" ]]; then
148
+ log "Session file not found for $SESSION_ID"
149
+ return
150
+ fi
151
+
152
+ # Extract and save facts
153
+ local facts
154
+ facts=$(extract_facts "$session_file" "$SESSION_ID")
155
+
156
+ local output_file="${MEMORY_DIR}/sessions/${SESSION_ID}.json"
157
+ mkdir -p "$(dirname "$output_file")"
158
+
159
+ # Merge with existing data if present
160
+ if [[ -f "$output_file" ]]; then
161
+ # Simple merge: update fields but preserve accumulated data
162
+ local existing_msg_count
163
+ existing_msg_count=$(jq -r '.accumulated_messages // 0' "$output_file" 2>/dev/null || echo 0)
164
+ local new_msg_count
165
+ new_msg_count=$(echo "$facts" | jq -r '.message_count')
166
+ local total_msgs=$((existing_msg_count + new_msg_count))
167
+
168
+ # Update but preserve accumulated decisions
169
+ local existing_decisions
170
+ existing_decisions=$(jq -r '.accumulated_decisions // []' "$output_file" 2>/dev/null || echo '[]')
171
+
172
+ echo "$facts" | jq --argjson decisions "$existing_decisions" --argjson total "$total_msgs" \
173
+ '. + {accumulated_messages: $total, accumulated_decisions: $decisions}' > "$output_file"
174
+ else
175
+ echo "$facts" | jq '. + {accumulated_messages: .message_count, accumulated_decisions: []}' > "$output_file"
176
+ fi
177
+
178
+ # Track this save
179
+ echo "{\"session_id\": \"$SESSION_ID\", \"saved_at\": \"$(date -Iseconds)\", \"precompact\": $precompact}" > "${STATE_FILE}"
180
+
181
+ if [[ "$precompact" == "true" ]]; then
182
+ log "[PRECOMPACT] Emergency save for $SESSION_ID"
183
+ else
184
+ log "Saved facts for $SESSION_ID ($(echo "$facts" | jq -r '.message_count') messages)"
185
+ fi
186
+ }
187
+
188
+ # Check if we should save (throttle to avoid too frequent saves)
189
+ should_save() {
190
+ local session_file="$1"
191
+
192
+ if [[ ! -f "${STATE_FILE}" ]]; then
193
+ return 0
194
+ fi
195
+
196
+ # Check last save time
197
+ local last_save
198
+ last_save=$(jq -r '.saved_at // empty' "${STATE_FILE}" 2>/dev/null || echo "")
199
+
200
+ if [[ -z "$last_save" ]]; then
201
+ return 0
202
+ fi
203
+
204
+ # Don't save more than once per 30 seconds
205
+ local last_save_epoch
206
+ last_save_epoch=$(date -d "$last_save" +%s 2>/dev/null || echo 0)
207
+ local now_epoch
208
+ now_epoch=$(date +%s)
209
+
210
+ if (( now_epoch - last_save_epoch < 30 )); then
211
+ return 1
212
+ fi
213
+
214
+ return 0
215
+ }
216
+
217
+ main() {
218
+ init
219
+
220
+ local precompact="false"
221
+ if [[ "${1:-}" == "--precompact" ]]; then
222
+ precompact="true"
223
+ fi
224
+
225
+ detect_session
226
+
227
+ if [[ -z "$SESSION_ID" ]]; then
228
+ log "No session detected, skipping"
229
+ exit 0
230
+ fi
231
+
232
+ # Find session file
233
+ local session_file=""
234
+ for dir in "${HOME}"/.claude/projects/*/; do
235
+ if [[ -f "${dir}${SESSION_ID}.jsonl" ]]; then
236
+ session_file="${dir}${SESSION_ID}.jsonl"
237
+ break
238
+ fi
239
+ done
240
+
241
+ if [[ -z "$session_file" ]]; then
242
+ log "Session file not found"
243
+ exit 1
244
+ fi
245
+
246
+ if ! should_save "$session_file"; then
247
+ log "Throttled (recent save)"
248
+ exit 0
249
+ fi
250
+
251
+ do_save "$precompact"
252
+ }
253
+
254
+ main "$@"
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env bash
2
+ # chat-recall wake-up hook — fires on SessionStart (matcher: startup|clear).
3
+ #
4
+ # Prints the project-scoped wake-up bundle (high-importance facts + current
5
+ # knowledge-graph facts) to stdout. Claude Code injects stdout into the new
6
+ # session's context. This gives manual sessions the same preamble that
7
+ # coolcode injects into its spawned sessions.
8
+ #
9
+ # Exit code 0 + stdout → injected as context.
10
+ # Any failure → silent exit 0. This hook is advisory and never blocks a session.
11
+ #
12
+ # Configurable via env:
13
+ # CHAT_RECALL_BIN — path to the chat-recall binary (default: which chat-recall)
14
+ # CHAT_RECALL_WAKEUP_TIMEOUT — seconds before we give up (default 10)
15
+
16
+ set -uo pipefail
17
+
18
+ if ! command -v jq >/dev/null 2>&1; then exit 0; fi
19
+
20
+ # Claude Code passes the hook payload as JSON on stdin; cwd is the project dir.
21
+ INPUT="$(cat 2>/dev/null || true)"
22
+ CWD="$(echo "$INPUT" | jq -r '.cwd // empty' 2>/dev/null || true)"
23
+ [[ -z "$CWD" ]] && CWD="$PWD"
24
+ PROJECT="$(basename "$CWD")"
25
+
26
+ CHAT_RECALL_BIN="${CHAT_RECALL_BIN:-$(command -v chat-recall || true)}"
27
+ if [[ -z "$CHAT_RECALL_BIN" ]] || [[ ! -x "$CHAT_RECALL_BIN" ]]; then exit 0; fi
28
+
29
+ TIMEOUT="${CHAT_RECALL_WAKEUP_TIMEOUT:-10}"
30
+ OUT="$(timeout "$TIMEOUT" "$CHAT_RECALL_BIN" memory wake-up -p "$PROJECT" 2>/dev/null || true)"
31
+ [[ -z "$OUT" ]] && exit 0
32
+
33
+ {
34
+ echo "<!-- chat-recall-wake-up -->"
35
+ echo "--- Prior knowledge (chat-recall wake-up, project: $PROJECT) ---"
36
+ echo "$OUT"
37
+ }
38
+
39
+ exit 0
package/package.json CHANGED
@@ -1,7 +1,41 @@
1
1
  {
2
2
  "name": "chat-recall",
3
- "version": "0.0.1",
4
- "description": "Cross-tool memory for AI coding sessions. Name reserved — first release coming shortly.",
5
- "license": "UNLICENSED",
6
- "homepage": "https://chatrecall.dev"
3
+ "version": "0.4.8",
4
+ "description": "Local-first memory for AI coding tools \u2014 indexes Claude Code / Gemini CLI / OpenCode / Codex sessions, exposes them over MCP, optionally syncs redacted history to a chat-recall server",
5
+ "type": "module",
6
+ "license": "Elastic-2.0",
7
+ "bin": {
8
+ "chat-recall": "./dist/cli.js",
9
+ "chat-recall-mcp": "./dist/mcp.js",
10
+ "chat-recall-watch": "./dist/watch.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "hooks",
15
+ "skills",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -b && node scripts/bundle.mjs && node scripts/postbuild.mjs",
21
+ "build:types": "tsc -b",
22
+ "auto-indexer": "tsx auto-indexer/indexer.ts"
23
+ },
24
+ "dependencies": {
25
+ "@modelcontextprotocol/sdk": "^1.0.0",
26
+ "@noble/ciphers": "^2.2.0",
27
+ "@noble/hashes": "^2.2.0",
28
+ "chalk": "^5.3.0",
29
+ "chokidar": "^3.5.3",
30
+ "commander": "^12.0.0",
31
+ "diff": "^9.0.0",
32
+ "dotenv": "^17.2.3",
33
+ "zod": "^3.22.0"
34
+ },
35
+ "optionalDependencies": {
36
+ "better-sqlite3": "12.9.0"
37
+ },
38
+ "devDependencies": {
39
+ "@chat-recall/engine": "*"
40
+ }
7
41
  }
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: chat-recall
3
+ description: >-
4
+ Recall past AI-coding work — prior sessions, decisions, and project history —
5
+ through the chat-recall MCP tools (mcp__chat-recall__recall_*). Use when the
6
+ user says "continue" / "pick up where we left off", "did we decide X",
7
+ "remember when we…", "what was I doing", "what do you know about this
8
+ project/me", or otherwise references earlier work that is not in the current
9
+ context. Also the entry point for the surfaces no focused skill owns: leaked
10
+ secrets ("did I paste an API key"), the shared task board and team activity
11
+ ("what are my open tasks", "what is my team working on"), and index health
12
+ ("is chat-recall working", "re-index my sessions"). This is the hub: it routes
13
+ to the focused chat-recall skills and lists every recall_* tool. Reach for it
14
+ whenever the answer lives in PAST work rather than the files in front of you.
15
+ ---
16
+
17
+ # chat-recall — cross-session memory for AI coding
18
+
19
+ chat-recall indexes your Claude Code, Gemini, OpenCode, Codex and Antigravity
20
+ sessions — plus plans, tasks, CLAUDE.md files, shell history and agent diaries —
21
+ into a searchable server with a temporal knowledge graph. When a request depends
22
+ on something that happened in an *earlier* session (a decision, a past fix, "what
23
+ were we doing"), don't guess or ask the user to re-explain — recall it.
24
+
25
+ All tools are MCP tools on the `chat-recall` server, named
26
+ `mcp__chat-recall__<tool>`.
27
+
28
+ **Reads are safe to call proactively. Writes are not.** Everything below is a
29
+ read except these, which change stored memory or state — treat each as an edit
30
+ and apply the test in `chat-recall-memory` before calling one:
31
+ `recall_kg_add`, `recall_kg_invalidate`, `recall_decision_record`,
32
+ `recall_diary_write`, `recall_set`, `recall_task_create`, `recall_task_update`,
33
+ `recall_security_dismiss`, `recall_rename_session`, `recall_regenerate_summary`,
34
+ `recall_reclassify`, `recall_index`, `recall_code_index`.
35
+
36
+ ## Route to the right skill
37
+
38
+ Match the intent, then read that skill and follow its workflow:
39
+
40
+ | The user wants… | Read skill |
41
+ | --- | --- |
42
+ | Continue / resume / pick up prior work; cold start on an ongoing task | `chat-recall-resume` |
43
+ | Find past conversations — "remember when", "have we done X", "find my notes on…" | `chat-recall-find` |
44
+ | Store or recall a decision / fact; "what do you know about…", "did we decide…" | `chat-recall-memory` |
45
+ | The state of a project — "what's been happening in X", cost, findings | `chat-recall-project` |
46
+ | What changed — edits, diffs, commits; "what was I doing 2h ago" | `chat-recall-changes` |
47
+
48
+ Leaked secrets, the shared task board, team activity and index health have no
49
+ focused skill — use the catalog below directly.
50
+
51
+ ## Tool catalog
52
+
53
+ Every `recall_*` tool. `packages/cli/src/skills-catalog.test.ts` fails when a
54
+ tool is registered and never named here, so adding a tool means placing it.
55
+
56
+ **Resume / cold start** — `recall_smart_resume` (structured resume bundle; needs a session id), `recall_recent` (list recent sessions), `recall_wake_up` (identity + high-signal facts), `recall_context` (structured dump of one session), `recall_show` (raw slice — returns 10 messages unless you raise `max_messages`), `recall_summary` (AI summary + outcome).
57
+ **Search** — `recall_search` (sessions; `include_outcome`, `like_session`), `recall_memory_search` (every memory type), `recall_memory_item` (read ONE item found by search, or browse a source type), `recall_user_prompts` (what the user actually typed), `recall_subagent_search` (inside subagent transcripts, whose work never reaches the main conversation), `recall_redundant_files` (before writing a new file, check you have not written one like it already).
58
+ **Project** — `recall_project_context` (rich dump), `recall_weekly_digest`, `recall_analytics_summary`, `recall_outcome_summary` (how many recent sessions actually shipped), `recall_code_findings` / `recall_code_actions` / `recall_code_projects` / `recall_code_index` / `recall_recommendations`.
59
+ **What changed** — `recall_edits_timeline` (cross-tool edits), `recall_diff` (per-session diffs), `recall_commits` (did it actually land), `recall_markers` (where a session went sideways).
60
+ **Durable memory / KG** — `recall_kg_query` / `recall_kg_add` / `recall_kg_invalidate` / `recall_kg_timeline` / `recall_kg_stats`, `recall_decision_record`, `recall_diary_write` / `recall_diary_read`, `recall_set` / `recall_get`.
61
+ **Team** — `recall_tasks` (the shared task board), `recall_task_create`, `recall_task_update` (status, assignee, comment; task ids look like `t_…`), `recall_team_activity` (per-teammate × per-project rollup), `recall_shares` (which projects are shared — private by default, nothing is visible to teammates until shared).
62
+ **Security** — `recall_security_summary` (leaked secrets that still need action — start here for "did I paste a key somewhere"), `recall_security_session` (findings for one session), `recall_security_dismiss` (mark rotated / false positive — do this only when the user confirms which), `recall_security_rules` (tenant detection rules; also tests a regex).
63
+ **Health / maintenance** — `recall_status` (is the index alive, what is synced), `recall_index` (sync now), `recall_heal_audit` (sessions whose rendered text is thinner than the raw archive, i.e. truncated upstream), `recall_regenerate_summary` (stored summary is stale or wrong), `recall_reclassify` (re-run the classifier over old chunks), `recall_rename_session`.
64
+
65
+ ## If you're unsure where to start
66
+
67
+ - Free-text "is there past work relevant to this?" → `recall_search` with `include_outcome: true`.
68
+ - Broader ("plans, tasks, CLAUDE.md, diaries too") → `recall_memory_search`.
69
+ - "What do you know about me / this project right now?" → `recall_wake_up` (add a project filter) or `recall_project_context`.
70
+ - "Continue where we left off" → you need a session id first. `recall_smart_resume`
71
+ takes one and REQUIRES it, so get the id from `recall_recent` (most recent work)
72
+ or `recall_search` (`include_outcome: true`, when the user described the task),
73
+ then resume. See `chat-recall-resume`.
74
+
75
+ Prefer one targeted recall over asking the user to recap. Cite what you found
76
+ (session id / decision) so the user can verify.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: chat-recall-changes
3
+ description: >-
4
+ See what changed across past AI-coding sessions with chat-recall. Use when the
5
+ user asks "what did I change 2h ago", "what files did we touch", "what happened
6
+ in that session", "did that session actually ship", "which sessions edited
7
+ <file>", or wants diffs/commits/edit-history that isn't in the current working
8
+ tree. Reconstructs edits, diffs, commits, and outcomes from indexed sessions.
9
+ ---
10
+
11
+ # What-changed with chat-recall
12
+
13
+ ## Recent edits across everything
14
+
15
+ `mcp__chat-recall__recall_edits_timeline` — chronological file edits across
16
+ every AI tool chat-recall indexes, read live from each tool's own session store.
17
+ `since_hours: 2` for "what was I doing recently"; `pattern` to filter by path;
18
+ `group_by: "session"` (+ wide `since_hours`) to answer "which sessions edited
19
+ <file> this month".
20
+
21
+ ## One session's changes
22
+
23
+ Every tool here takes a NAMED `session_id` (not a positional argument).
24
+
25
+ - `mcp__chat-recall__recall_diff` — per-file unified diffs of what a session
26
+ actually changed (detects reverts). `files_only: true` = just the touched-files
27
+ list; `context_only: true` = per-file add/remove stats.
28
+ - `mcp__chat-recall__recall_commits` — git commits that landed in the
29
+ session's edit window, grouped by repo. Use to verify "shipped" claims: many
30
+ edits but no commit = work stayed local.
31
+ - `mcp__chat-recall__recall_summary` — AI summary + outcome classification
32
+ (shipped / interrupted / abandoned) + last-claim-vs-user-reaction.
33
+ - `mcp__chat-recall__recall_markers` — per-prompt sentiment/correction
34
+ markers (frustrated, correction, approval) to spot where a session went sideways.
35
+
36
+ ## Across many sessions
37
+
38
+ `mcp__chat-recall__recall_outcome_summary` — how sessions ended over the last N
39
+ days (shipped / interrupted / abandoned / in_progress). Use for "am I finishing
40
+ what I start", never for one session — `recall_summary` answers that.
41
+
42
+ ## Workflow
43
+
44
+ 1. "What was I doing recently" → `recall_edits_timeline` (`since_hours`).
45
+ 2. "Which sessions touched <file>" → `recall_edits_timeline`
46
+ (`pattern`, `group_by: "session"`, wide window).
47
+ 3. "What did session X change / did it ship" → `recall_diff` + `recall_commits`
48
+ (+ `recall_summary` for the outcome).
49
+ 4. Don't claim a session shipped without `recall_commits` confirming a matching
50
+ commit — edits alone can be local-only.
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: chat-recall-find
3
+ description: >-
4
+ Find past AI-coding work with chat-recall. Use when the user asks "remember
5
+ when we…", "have we done X before", "find my notes/sessions on…", "where did we
6
+ discuss Y", "what did I ask about Z", or otherwise wants to locate earlier
7
+ conversations, plans, tasks, or notes across all their AI tools. Searches the
8
+ unified memory (sessions, plans, tasks, CLAUDE.md, history, diaries).
9
+ ---
10
+
11
+ # Finding past work with chat-recall
12
+
13
+ ## Pick the search tool
14
+
15
+ - `mcp__chat-recall__recall_search` — search SESSIONS. Free-text query.
16
+ - `include_outcome: true` → each hit gets a shipped/interrupted/abandoned line
17
+ so you can judge relevance fast.
18
+ - `like_session: <id>` → find sessions similar to a given one.
19
+ - `project_filter`, `top_k` to narrow.
20
+ - `mcp__chat-recall__recall_memory_search` — search ALL memory types, not just
21
+ sessions. Use this when the answer might be in a plan, task list, CLAUDE.md, or
22
+ an agent diary — not only a conversation. Omit `source_types` to search
23
+ everything; pass it to narrow. The conversation-ish types are
24
+ `['session','plan','task','claude_md','paste','history','diary','agent_memory']`,
25
+ and the toolkit types — what is CONFIGURED rather than what was said — are
26
+ `['skill','mcp','command','agent','hook','plugin']`.
27
+ - `mcp__chat-recall__recall_user_prompts` — search only what the USER actually
28
+ typed (assistant output stripped). Best for "what did I ask about X",
29
+ "what was I requesting yesterday".
30
+ - `mcp__chat-recall__recall_subagent_search` — search inside SUBAGENT
31
+ transcripts. Explore/compact/aside sub-tasks run within a session and their
32
+ work never appears in the main conversation, so a normal session search cannot
33
+ find it. Reach for this when a session clearly did work you cannot locate.
34
+ - `mcp__chat-recall__recall_redundant_files` — before creating a file, check
35
+ whether you have written one like it before. Scores a filename against every
36
+ file in the synced history.
37
+
38
+ ## From a hit to the content
39
+
40
+ Every tool here takes a NAMED `session_id` (not a positional argument).
41
+
42
+ - `mcp__chat-recall__recall_show` — read the session slice (`around_line`,
43
+ `from_end`, `include_code: true` for diffs/commands). It returns **10 messages
44
+ by default**: raise `max_messages` before telling the user what a session
45
+ contains, or you will describe a tenth of it as the whole.
46
+ - `mcp__chat-recall__recall_summary` — AI summary + outcome.
47
+ - `mcp__chat-recall__recall_memory_item` — read ONE item in full (or its links)
48
+ once search has found it. `mode=browse` lists a whole source type.
49
+ - Plans/tasks: `recall_memory_search(source_types: ['plan','task'])` to find,
50
+ then `recall_show` with the plan id to read the full plan.
51
+
52
+ ## Strategy
53
+
54
+ 1. Sessions-only question → `recall_search` (add `include_outcome: true`).
55
+ 2. Might be a plan/task/note/diary → `recall_memory_search` (set `source_types`).
56
+ 3. "What did *I* ask" → `recall_user_prompts`.
57
+ 4. Zero results → broaden the query by dropping qualifiers, drop or widen
58
+ `project_filter`, or try the other search tool. Neither search tool has a
59
+ date/time filter, so do NOT try to narrow by time here — for a time window
60
+ use `recall_recent` (`since_hours`) or `recall_edits_timeline` instead.
61
+ Then open the best hit with `recall_show`.
62
+ 5. Work you cannot find in the session itself → `recall_subagent_search`.
63
+
64
+ Report the session id / source of each result so the user can jump to it.