@the-bearded-bear/claude-craft 7.34.0 → 7.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ # Memory Lifecycle — Persistent memory across Claude Code sessions
2
+
3
+ **Inspiré de** [thedotmack/claude-mem](https://github.com/thedotmack/claude-mem) (49.6k stars).
4
+
5
+ Système de mémoire persistante **100% local** qui capture sessions, prompts, et utilisation d'outils dans une base SQLite locale, permettant le rappel cross-sessions sans cloud ni télémétrie.
6
+
7
+ ## Architecture
8
+
9
+ ```
10
+ Session lifecycle
11
+ ├─ SessionStart → init DB + recall previous session summary
12
+ ├─ UserPromptSubmit → log prompt preview (200 chars max)
13
+ ├─ PostToolUse → log Edit/Write/Bash events (target + summary)
14
+ ├─ PreCompact → preserve context + re-inject before compaction
15
+ └─ SessionEnd → compute session summary
16
+ ```
17
+
18
+ ## Schéma SQLite
19
+
20
+ ```sql
21
+ sessions (id, started_at, ended_at, project_dir, git_branch, git_commit, summary)
22
+ prompts (id, session_id, submitted_at, prompt_preview, token_estimate)
23
+ tool_events (id, session_id, occurred_at, tool_name, target_path, summary)
24
+ compactions (id, session_id, compacted_at, preserved_context)
25
+ ```
26
+
27
+ ## Installation
28
+
29
+ ### 1. Prérequis
30
+
31
+ - `sqlite3` (package système : `apt install sqlite3` / `brew install sqlite3`)
32
+ - `jq` (package système : `apt install jq` / `brew install jq`)
33
+ - `bash` 4+
34
+
35
+ ### 2. Activer les hooks
36
+
37
+ Copier le contenu de `.claude/templates/hooks/memory-lifecycle.json` dans votre `.claude/settings.json` :
38
+
39
+ ```bash
40
+ # Fusion manuelle dans .claude/settings.json
41
+ cat .claude/templates/hooks/memory-lifecycle.json
42
+ ```
43
+
44
+ Ou via la commande Claude Craft (à venir) : `/common:setup-memory-lifecycle`.
45
+
46
+ ### 3. Vérifier
47
+
48
+ Démarrer une nouvelle session Claude Code. La base est créée automatiquement :
49
+
50
+ ```bash
51
+ ls -la .claude/memory.db
52
+ sqlite3 .claude/memory.db "SELECT * FROM sessions LIMIT 1;"
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### Consulter les sessions passées
58
+
59
+ ```bash
60
+ sqlite3 .claude/memory.db \
61
+ "SELECT id, started_at, summary FROM sessions ORDER BY started_at DESC LIMIT 10;"
62
+ ```
63
+
64
+ ### Top fichiers édités cette semaine
65
+
66
+ ```bash
67
+ sqlite3 .claude/memory.db <<SQL
68
+ SELECT target_path, COUNT(*) as edits
69
+ FROM tool_events
70
+ WHERE tool_name IN ('Edit', 'Write')
71
+ AND occurred_at > datetime('now', '-7 days')
72
+ GROUP BY target_path
73
+ ORDER BY edits DESC
74
+ LIMIT 10;
75
+ SQL
76
+ ```
77
+
78
+ ### Recall depuis une autre session
79
+
80
+ Automatique via `SessionStart` — le résumé de la dernière session est injecté en `systemMessage`.
81
+
82
+ ## Confidentialité
83
+
84
+ - **100% local** — base SQLite dans `.claude/memory.db`
85
+ - **Zéro télémétrie** — pas de network call
86
+ - **Gitignored** — jamais commité (`.claude/memory.db` dans `.gitignore`)
87
+ - **Previews only** — prompts tronqués à 200 chars, tool output à 300 chars
88
+ - **Hash projet** — session ID contient un hash SHA1 du path, pas le path complet
89
+
90
+ ## Nettoyage
91
+
92
+ Purger les sessions de plus de 90 jours :
93
+
94
+ ```bash
95
+ sqlite3 .claude/memory.db \
96
+ "DELETE FROM sessions WHERE started_at < datetime('now', '-90 days');
97
+ DELETE FROM prompts WHERE session_id NOT IN (SELECT id FROM sessions);
98
+ DELETE FROM tool_events WHERE session_id NOT IN (SELECT id FROM sessions);
99
+ VACUUM;"
100
+ ```
101
+
102
+ ## Désactivation
103
+
104
+ Retirer les hooks de `.claude/settings.json`. La base `.claude/memory.db` peut être supprimée sans impact.
105
+
106
+ ## Limitations (v7.35.0)
107
+
108
+ - Pas de compression IA des sessions (claude-mem original utilise Anthropic API pour summarize → hors scope local-first)
109
+ - Pas de Web UI (prévu en v8+ si demande)
110
+ - Pas de recherche sémantique (SQL LIKE uniquement)
111
+ - Un session ID par jour par projet (simplicité vs granularité)
112
+
113
+ ## Ressources
114
+
115
+ - [claude-mem](https://github.com/thedotmack/claude-mem) — implémentation originale
116
+ - `.claude/templates/hooks/memory-lifecycle.json` — template hook
117
+ - `.claude/rules/12-context-management.md` — stratégie contexte
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env bash
2
+ # _db.sh — Shared DB helpers for memory-lifecycle hooks.
3
+ # Sourced by other scripts, not executed directly.
4
+
5
+ set -euo pipefail
6
+
7
+ MEMORY_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.claude"
8
+ MEMORY_DB="$MEMORY_DIR/memory.db"
9
+
10
+ mkdir -p "$MEMORY_DIR"
11
+
12
+ # Initialize schema if DB doesn't exist
13
+ init_memory_db() {
14
+ if [[ ! -f "$MEMORY_DB" ]]; then
15
+ sqlite3 "$MEMORY_DB" <<'SQL'
16
+ CREATE TABLE IF NOT EXISTS sessions (
17
+ id TEXT PRIMARY KEY,
18
+ started_at TEXT NOT NULL,
19
+ ended_at TEXT,
20
+ project_dir TEXT,
21
+ git_branch TEXT,
22
+ git_commit TEXT,
23
+ summary TEXT
24
+ );
25
+
26
+ CREATE TABLE IF NOT EXISTS prompts (
27
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
28
+ session_id TEXT NOT NULL REFERENCES sessions(id),
29
+ submitted_at TEXT NOT NULL,
30
+ prompt_preview TEXT,
31
+ token_estimate INTEGER
32
+ );
33
+
34
+ CREATE TABLE IF NOT EXISTS tool_events (
35
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
36
+ session_id TEXT NOT NULL REFERENCES sessions(id),
37
+ occurred_at TEXT NOT NULL,
38
+ tool_name TEXT,
39
+ target_path TEXT,
40
+ summary TEXT
41
+ );
42
+
43
+ CREATE TABLE IF NOT EXISTS compactions (
44
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
45
+ session_id TEXT NOT NULL REFERENCES sessions(id),
46
+ compacted_at TEXT NOT NULL,
47
+ preserved_context TEXT
48
+ );
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at DESC);
51
+ CREATE INDEX IF NOT EXISTS idx_prompts_session ON prompts(session_id);
52
+ CREATE INDEX IF NOT EXISTS idx_tools_session ON tool_events(session_id);
53
+ SQL
54
+ fi
55
+ }
56
+
57
+ # Get or create current session id (one per day per project)
58
+ current_session_id() {
59
+ local today
60
+ today=$(date -u +%Y%m%d)
61
+ local project_hash
62
+ project_hash=$(echo -n "${CLAUDE_PROJECT_DIR:-$(pwd)}" | sha1sum | cut -c1-8)
63
+ echo "${today}-${project_hash}"
64
+ }
65
+
66
+ # Safe SQL escape (basic)
67
+ sql_escape() {
68
+ printf '%s' "$1" | sed "s/'/''/g"
69
+ }
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ # PostToolUse hook — log significant tool events (Edit/Write/Bash only per matcher).
3
+
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
7
+ # shellcheck source=./_db.sh
8
+ source "$SCRIPT_DIR/_db.sh"
9
+
10
+ if ! command -v sqlite3 &>/dev/null; then
11
+ echo '{}' ; exit 0
12
+ fi
13
+
14
+ init_memory_db
15
+
16
+ SESSION_ID=$(current_session_id)
17
+ NOW=$(date -u -Iseconds)
18
+
19
+ INPUT=$(cat 2>/dev/null || echo "")
20
+ TOOL_NAME=""
21
+ TARGET=""
22
+ SUMMARY=""
23
+
24
+ if [[ -n "$INPUT" ]] && command -v jq &>/dev/null; then
25
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null || echo "")
26
+ TARGET=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.command // ""' 2>/dev/null | cut -c1-300)
27
+ SUMMARY=$(echo "$INPUT" | jq -r '.tool_response.summary // ""' 2>/dev/null | cut -c1-300)
28
+ fi
29
+
30
+ [[ -z "$TOOL_NAME" ]] && { echo '{}'; exit 0; }
31
+
32
+ sqlite3 "$MEMORY_DB" <<SQL
33
+ INSERT INTO tool_events(session_id, occurred_at, tool_name, target_path, summary)
34
+ VALUES ('$(sql_escape "$SESSION_ID")', '$NOW', '$(sql_escape "$TOOL_NAME")', '$(sql_escape "$TARGET")', '$(sql_escape "$SUMMARY")');
35
+ SQL
36
+
37
+ echo '{}'
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # PreCompact hook — capture critical context before compaction, re-inject it.
3
+
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
7
+ # shellcheck source=./_db.sh
8
+ source "$SCRIPT_DIR/_db.sh"
9
+
10
+ if ! command -v sqlite3 &>/dev/null || ! command -v jq &>/dev/null; then
11
+ echo '{}' ; exit 0
12
+ fi
13
+
14
+ init_memory_db
15
+
16
+ SESSION_ID=$(current_session_id)
17
+ NOW=$(date -u -Iseconds)
18
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
19
+
20
+ # Build preserved context: essentials + recent tool events + recent prompts
21
+ ESSENTIALS=""
22
+ if [[ -f "$PROJECT_DIR/.claude/context-essentials.md" ]]; then
23
+ ESSENTIALS=$(head -60 "$PROJECT_DIR/.claude/context-essentials.md")
24
+ fi
25
+
26
+ RECENT_TOOLS=$(sqlite3 "$MEMORY_DB" "SELECT tool_name || ' → ' || COALESCE(target_path,'') FROM tool_events WHERE session_id='$SESSION_ID' ORDER BY occurred_at DESC LIMIT 10;" 2>/dev/null || echo "")
27
+
28
+ RECENT_PROMPTS=$(sqlite3 "$MEMORY_DB" "SELECT prompt_preview FROM prompts WHERE session_id='$SESSION_ID' ORDER BY submitted_at DESC LIMIT 3;" 2>/dev/null || echo "")
29
+
30
+ CONTEXT="=== CRITICAL CONTEXT PRESERVED ==="
31
+ [[ -n "$ESSENTIALS" ]] && CONTEXT+=$'\n\n## Project essentials\n'"$ESSENTIALS"
32
+ [[ -n "$RECENT_PROMPTS" ]] && CONTEXT+=$'\n\n## Recent prompts\n'"$RECENT_PROMPTS"
33
+ [[ -n "$RECENT_TOOLS" ]] && CONTEXT+=$'\n\n## Recent tool events\n'"$RECENT_TOOLS"
34
+
35
+ # Persist
36
+ sqlite3 "$MEMORY_DB" <<SQL
37
+ INSERT INTO compactions(session_id, compacted_at, preserved_context)
38
+ VALUES ('$(sql_escape "$SESSION_ID")', '$NOW', '$(sql_escape "$CONTEXT")');
39
+ SQL
40
+
41
+ # Re-inject
42
+ jq -n --arg msg "$CONTEXT" '{"systemMessage": $msg}'
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+ # UserPromptSubmit hook — log each user prompt (preview only, no full content).
3
+
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
7
+ # shellcheck source=./_db.sh
8
+ source "$SCRIPT_DIR/_db.sh"
9
+
10
+ if ! command -v sqlite3 &>/dev/null; then
11
+ echo '{}' ; exit 0
12
+ fi
13
+
14
+ init_memory_db
15
+
16
+ SESSION_ID=$(current_session_id)
17
+ NOW=$(date -u -Iseconds)
18
+
19
+ # Read prompt from stdin (Claude Code passes it as JSON)
20
+ INPUT=$(cat 2>/dev/null || echo "")
21
+ PROMPT=""
22
+ if [[ -n "$INPUT" ]] && command -v jq &>/dev/null; then
23
+ PROMPT=$(echo "$INPUT" | jq -r '.prompt // .user_prompt // ""' 2>/dev/null || echo "")
24
+ fi
25
+
26
+ # Preview : first 200 chars, sanitized
27
+ PREVIEW=$(printf '%s' "$PROMPT" | tr -d '\n' | cut -c1-200)
28
+ TOKEN_EST=$(( ${#PROMPT} / 4 ))
29
+
30
+ sqlite3 "$MEMORY_DB" <<SQL
31
+ INSERT INTO prompts(session_id, submitted_at, prompt_preview, token_estimate)
32
+ VALUES ('$(sql_escape "$SESSION_ID")', '$NOW', '$(sql_escape "$PREVIEW")', $TOKEN_EST);
33
+ SQL
34
+
35
+ echo '{}'
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env bash
2
+ # SessionEnd hook — finalize session, compute summary from tool events + prompts.
3
+
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
7
+ # shellcheck source=./_db.sh
8
+ source "$SCRIPT_DIR/_db.sh"
9
+
10
+ if ! command -v sqlite3 &>/dev/null; then
11
+ echo '{}' ; exit 0
12
+ fi
13
+
14
+ init_memory_db
15
+
16
+ SESSION_ID=$(current_session_id)
17
+ NOW=$(date -u -Iseconds)
18
+
19
+ PROMPT_COUNT=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM prompts WHERE session_id='$SESSION_ID';" 2>/dev/null || echo 0)
20
+ TOOL_COUNT=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(*) FROM tool_events WHERE session_id='$SESSION_ID';" 2>/dev/null || echo 0)
21
+ FILES_EDITED=$(sqlite3 "$MEMORY_DB" "SELECT COUNT(DISTINCT target_path) FROM tool_events WHERE session_id='$SESSION_ID' AND tool_name IN ('Edit','Write');" 2>/dev/null || echo 0)
22
+
23
+ # Top 5 edited files
24
+ TOP_FILES=$(sqlite3 "$MEMORY_DB" "SELECT target_path FROM tool_events WHERE session_id='$SESSION_ID' AND tool_name IN ('Edit','Write') AND target_path != '' GROUP BY target_path ORDER BY COUNT(*) DESC LIMIT 5;" 2>/dev/null | tr '\n' '|' || echo "")
25
+
26
+ SUMMARY="Session $SESSION_ID: $PROMPT_COUNT prompts, $TOOL_COUNT tool events, $FILES_EDITED files edited. Top: $TOP_FILES"
27
+
28
+ sqlite3 "$MEMORY_DB" <<SQL
29
+ UPDATE sessions SET ended_at='$NOW', summary='$(sql_escape "$SUMMARY")' WHERE id='$(sql_escape "$SESSION_ID")';
30
+ SQL
31
+
32
+ echo '{}'
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ # SessionStart hook — open or reuse today's session row.
3
+ # Output: JSON with systemMessage recalling last session summary (if any).
4
+
5
+ set -euo pipefail
6
+
7
+ SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
8
+ # shellcheck source=./_db.sh
9
+ source "$SCRIPT_DIR/_db.sh"
10
+
11
+ if ! command -v sqlite3 &>/dev/null; then
12
+ echo '{}' ; exit 0
13
+ fi
14
+
15
+ init_memory_db
16
+
17
+ SESSION_ID=$(current_session_id)
18
+ NOW=$(date -u -Iseconds)
19
+ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
20
+
21
+ GIT_BRANCH=$(git -C "$PROJECT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
22
+ GIT_COMMIT=$(git -C "$PROJECT_DIR" rev-parse --short HEAD 2>/dev/null || echo "")
23
+
24
+ sqlite3 "$MEMORY_DB" <<SQL
25
+ INSERT OR IGNORE INTO sessions(id, started_at, project_dir, git_branch, git_commit)
26
+ VALUES ('$(sql_escape "$SESSION_ID")', '$NOW', '$(sql_escape "$PROJECT_DIR")', '$(sql_escape "$GIT_BRANCH")', '$(sql_escape "$GIT_COMMIT")');
27
+ SQL
28
+
29
+ # Recall last completed session summary (if any)
30
+ LAST_SUMMARY=$(sqlite3 "$MEMORY_DB" "SELECT summary FROM sessions WHERE id != '$SESSION_ID' AND summary IS NOT NULL ORDER BY started_at DESC LIMIT 1;" 2>/dev/null || echo "")
31
+
32
+ if [[ -n "$LAST_SUMMARY" ]] && command -v jq &>/dev/null; then
33
+ MSG="📚 Recall from last session:\n\n$LAST_SUMMARY"
34
+ jq -n --arg msg "$MSG" '{"systemMessage": $msg}'
35
+ else
36
+ echo '{}'
37
+ fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@the-bearded-bear/claude-craft",
3
- "version": "7.34.0",
3
+ "version": "7.35.0",
4
4
  "description": "A comprehensive framework for AI-assisted development with Claude Code. Install standardized rules, agents, and commands for your projects.",
5
5
  "type": "module",
6
6
  "main": "cli/index.js",