memento-mcp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# hook-toast.sh — tmux popup notifications for agent hooks.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# hook-toast.sh <system> <message> # one-shot toast (auto-closes after 2s)
|
|
6
|
+
# hook-toast.sh <system> --status <id> # start a multi-stage toast (poll mode)
|
|
7
|
+
# hook-toast.sh --update <id> <message> # update a running toast
|
|
8
|
+
# hook-toast.sh --close <id> # close a running toast (after delay)
|
|
9
|
+
#
|
|
10
|
+
# Built-in systems: fathom, memento
|
|
11
|
+
# fathom → 📝 purple (colour141)
|
|
12
|
+
# memento → 🧠 teal (colour37)
|
|
13
|
+
#
|
|
14
|
+
# Any other system name works too — gets a default icon and grey border.
|
|
15
|
+
#
|
|
16
|
+
# Multi-stage example (PreCompact):
|
|
17
|
+
# hook-toast.sh memento --status precompact
|
|
18
|
+
# hook-toast.sh --update precompact "⏳ Getting context..."
|
|
19
|
+
# hook-toast.sh --update precompact "⏳ Extracting memories..."
|
|
20
|
+
# hook-toast.sh --update precompact "✓ Stored 7 memories"
|
|
21
|
+
# hook-toast.sh --close precompact
|
|
22
|
+
|
|
23
|
+
TOAST_DIR="/tmp/hook-toast"
|
|
24
|
+
mkdir -p "$TOAST_DIR"
|
|
25
|
+
|
|
26
|
+
# Bail silently if not in tmux
|
|
27
|
+
if ! tmux info &>/dev/null; then
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
get_style() {
|
|
32
|
+
case "$1" in
|
|
33
|
+
memento) echo "colour37" ;;
|
|
34
|
+
fathom) echo "colour141" ;;
|
|
35
|
+
*) echo "colour245" ;;
|
|
36
|
+
esac
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get_icon() {
|
|
40
|
+
case "$1" in
|
|
41
|
+
memento) echo "🧠" ;;
|
|
42
|
+
fathom) echo "📝" ;;
|
|
43
|
+
*) echo "📌" ;;
|
|
44
|
+
esac
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
get_title() {
|
|
48
|
+
case "$1" in
|
|
49
|
+
memento) echo "Memento" ;;
|
|
50
|
+
fathom) echo "Fathom" ;;
|
|
51
|
+
*) echo "$1" ;;
|
|
52
|
+
esac
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# One-shot toast
|
|
56
|
+
toast_oneshot() {
|
|
57
|
+
local system="$1"
|
|
58
|
+
local message="$2"
|
|
59
|
+
local colour icon title
|
|
60
|
+
colour=$(get_style "$system")
|
|
61
|
+
icon=$(get_icon "$system")
|
|
62
|
+
title=$(get_title "$system")
|
|
63
|
+
|
|
64
|
+
(tmux display-popup -x R -y 0 -w 42 -h 3 \
|
|
65
|
+
-s "fg=$colour" -T " $icon $title " -E \
|
|
66
|
+
"echo ' $message'; sleep 2" &>/dev/null &)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Start a multi-stage toast (polling status file)
|
|
70
|
+
toast_start() {
|
|
71
|
+
local system="$1"
|
|
72
|
+
local id="$2"
|
|
73
|
+
local status_file="$TOAST_DIR/$id"
|
|
74
|
+
local colour icon title
|
|
75
|
+
colour=$(get_style "$system")
|
|
76
|
+
icon=$(get_icon "$system")
|
|
77
|
+
title=$(get_title "$system")
|
|
78
|
+
|
|
79
|
+
echo "⏳ Starting..." > "$status_file"
|
|
80
|
+
|
|
81
|
+
(tmux display-popup -x R -y 0 -w 42 -h 3 \
|
|
82
|
+
-s "fg=$colour" -T " $icon $title " -E "
|
|
83
|
+
LAST=''
|
|
84
|
+
while [ -f '$status_file' ]; do
|
|
85
|
+
MSG=\$(cat '$status_file' 2>/dev/null)
|
|
86
|
+
if [ \"\$MSG\" != \"\$LAST\" ]; then
|
|
87
|
+
clear
|
|
88
|
+
echo \" \$MSG\"
|
|
89
|
+
LAST=\"\$MSG\"
|
|
90
|
+
fi
|
|
91
|
+
case \"\$MSG\" in ✓*|✗*) sleep 2; break ;; esac
|
|
92
|
+
sleep 0.2
|
|
93
|
+
done
|
|
94
|
+
" &>/dev/null &)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Update a running toast
|
|
98
|
+
toast_update() {
|
|
99
|
+
local id="$1"
|
|
100
|
+
local message="$2"
|
|
101
|
+
echo "$message" > "$TOAST_DIR/$id"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Close a running toast (remove status file — popup exits on next poll)
|
|
105
|
+
toast_close() {
|
|
106
|
+
local id="$1"
|
|
107
|
+
# Give the popup time to display the final message
|
|
108
|
+
sleep 2
|
|
109
|
+
rm -f "$TOAST_DIR/$id"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# --- Argument parsing ---
|
|
113
|
+
case "${1:-}" in
|
|
114
|
+
--update)
|
|
115
|
+
toast_update "$2" "$3"
|
|
116
|
+
;;
|
|
117
|
+
--close)
|
|
118
|
+
toast_close "$2"
|
|
119
|
+
;;
|
|
120
|
+
--*)
|
|
121
|
+
echo "Unknown option: $1" >&2
|
|
122
|
+
exit 1
|
|
123
|
+
;;
|
|
124
|
+
"")
|
|
125
|
+
echo "Usage: hook-toast.sh <system> <message>" >&2
|
|
126
|
+
echo " hook-toast.sh <system> --status <id>" >&2
|
|
127
|
+
echo " hook-toast.sh --update <id> <message>" >&2
|
|
128
|
+
echo " hook-toast.sh --close <id>" >&2
|
|
129
|
+
exit 1
|
|
130
|
+
;;
|
|
131
|
+
*)
|
|
132
|
+
SYSTEM="$1"
|
|
133
|
+
shift
|
|
134
|
+
if [ "${1:-}" = "--status" ]; then
|
|
135
|
+
toast_start "$SYSTEM" "$2"
|
|
136
|
+
else
|
|
137
|
+
toast_oneshot "$SYSTEM" "$*"
|
|
138
|
+
fi
|
|
139
|
+
;;
|
|
140
|
+
esac
|
|
@@ -8,17 +8,27 @@
|
|
|
8
8
|
set -o pipefail
|
|
9
9
|
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
TOAST="$SCRIPT_DIR/hook-toast.sh"
|
|
12
|
+
|
|
13
|
+
# Toast: start multi-stage
|
|
14
|
+
"$TOAST" memento --status distill &>/dev/null
|
|
15
|
+
"$TOAST" --update distill "⏳ Getting context..." &>/dev/null
|
|
16
|
+
|
|
11
17
|
INPUT=$(cat)
|
|
12
18
|
|
|
13
19
|
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path' | sed "s|~|$HOME|")
|
|
14
20
|
|
|
15
21
|
# Only distill if transcript exists and has content
|
|
16
22
|
if [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
23
|
+
"$TOAST" --update distill "✗ No transcript found" &>/dev/null
|
|
24
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
17
25
|
exit 0
|
|
18
26
|
fi
|
|
19
27
|
|
|
20
28
|
LINE_COUNT=$(wc -l < "$TRANSCRIPT_PATH")
|
|
21
29
|
if [ "$LINE_COUNT" -lt 2 ]; then
|
|
30
|
+
"$TOAST" --update distill "✓ Skipped (tiny conversation)" &>/dev/null
|
|
31
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
22
32
|
exit 0
|
|
23
33
|
fi
|
|
24
34
|
|
|
@@ -79,9 +89,14 @@ else
|
|
|
79
89
|
fi
|
|
80
90
|
|
|
81
91
|
if [ ${#TRANSCRIPT_TEXT} -lt 200 ]; then
|
|
92
|
+
"$TOAST" --update distill "✓ Skipped (too short)" &>/dev/null
|
|
93
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
82
94
|
exit 0 # Too short to distill anything useful
|
|
83
95
|
fi
|
|
84
96
|
|
|
97
|
+
# Toast: extracting
|
|
98
|
+
"$TOAST" --update distill "⏳ Extracting memories..." &>/dev/null
|
|
99
|
+
|
|
85
100
|
DISTILL_MODEL="${DISTILL_MODEL:-llama}"
|
|
86
101
|
|
|
87
102
|
# claude-code path: run extraction locally via claude -p, push to /v1/memories/ingest
|
|
@@ -166,9 +181,15 @@ print(json.dumps({'memories': parsed, 'source': 'distill:claude-code'}))
|
|
|
166
181
|
-d "$INGEST_PAYLOAD" \
|
|
167
182
|
"$MEMENTO_API/v1/memories/ingest" > /dev/null 2>&1
|
|
168
183
|
|
|
184
|
+
"$TOAST" --update distill "✓ Stored ${MEMORY_COUNT} memories" &>/dev/null
|
|
185
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
186
|
+
|
|
169
187
|
python3 -c "import json,sys; print(json.dumps({'systemMessage': sys.argv[1]}))" \
|
|
170
188
|
"Memento Distill (claude-code): ${MEMORY_COUNT} memories — ${TYPE_BREAKDOWN}"
|
|
171
189
|
else
|
|
190
|
+
"$TOAST" --update distill "✓ No memories extracted" &>/dev/null
|
|
191
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
192
|
+
|
|
172
193
|
python3 -c "import json,sys; print(json.dumps({'systemMessage': sys.argv[1]}))" \
|
|
173
194
|
"Memento Distill (claude-code): no memories extracted"
|
|
174
195
|
fi
|
|
@@ -206,9 +227,15 @@ MEMORY_COUNT=$(echo "$DISTILL_SUMMARY" | cut -d'|' -f1)
|
|
|
206
227
|
TYPE_BREAKDOWN=$(echo "$DISTILL_SUMMARY" | cut -d'|' -f2)
|
|
207
228
|
|
|
208
229
|
if [ "${MEMORY_COUNT:-0}" -gt 0 ] 2>/dev/null; then
|
|
230
|
+
"$TOAST" --update distill "✓ Stored ${MEMORY_COUNT} memories" &>/dev/null
|
|
231
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
232
|
+
|
|
209
233
|
python3 -c "import json,sys; print(json.dumps({'systemMessage': sys.argv[1]}))" \
|
|
210
234
|
"Memento Distill: ${MEMORY_COUNT} memories — ${TYPE_BREAKDOWN}"
|
|
211
235
|
else
|
|
236
|
+
"$TOAST" --update distill "✓ No memories extracted" &>/dev/null
|
|
237
|
+
("$TOAST" --close distill &>/dev/null &)
|
|
238
|
+
|
|
212
239
|
python3 -c "import json,sys; print(json.dumps({'systemMessage': sys.argv[1]}))" \
|
|
213
240
|
"Memento Distill: no memories extracted"
|
|
214
241
|
fi
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
set -o pipefail
|
|
11
11
|
|
|
12
12
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
13
|
+
TOAST="$SCRIPT_DIR/hook-toast.sh"
|
|
13
14
|
|
|
14
15
|
# --- Config from .memento.json (if present) ---
|
|
15
16
|
CONFIG_JSON=$(python3 -c "
|
|
@@ -80,6 +81,9 @@ ACTIVE_TMP=$(mktemp)
|
|
|
80
81
|
SKIP_TMP=$(mktemp)
|
|
81
82
|
trap 'rm -f "$IDENTITY_TMP" "$ACTIVE_TMP" "$SKIP_TMP"' EXIT
|
|
82
83
|
|
|
84
|
+
# Toast: loading identity
|
|
85
|
+
"$TOAST" memento "⏳ Loading identity..." &>/dev/null
|
|
86
|
+
|
|
83
87
|
# Fetch all three endpoints in parallel
|
|
84
88
|
curl -s --max-time 3 -H "$AUTH_HEADER" -H "$WS_HEADER" \
|
|
85
89
|
"$MEMENTO_API/v1/identity" > "$IDENTITY_TMP" 2>/dev/null &
|
|
@@ -159,4 +163,7 @@ print(json.dumps({
|
|
|
159
163
|
}))
|
|
160
164
|
" "$IDENTITY_TMP" "$ACTIVE_TMP" "$SKIP_TMP" 2>/dev/null
|
|
161
165
|
|
|
166
|
+
# Toast: done
|
|
167
|
+
"$TOAST" memento "✓ Identity loaded" &>/dev/null
|
|
168
|
+
|
|
162
169
|
exit 0
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
set -o pipefail
|
|
7
7
|
|
|
8
8
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
9
|
+
TOAST="$SCRIPT_DIR/hook-toast.sh"
|
|
9
10
|
|
|
10
11
|
# --- Config from .memento.json (if present) ---
|
|
11
12
|
CONFIG_JSON=$(python3 -c "
|
|
@@ -74,6 +75,9 @@ fi
|
|
|
74
75
|
# Truncate to first 500 chars for the query
|
|
75
76
|
QUERY="${ASSISTANT_MSG:0:500}"
|
|
76
77
|
|
|
78
|
+
# Toast: start retrieving
|
|
79
|
+
"$TOAST" memento "⏳ Autonomous recall..." &>/dev/null
|
|
80
|
+
|
|
77
81
|
# Call Memento /v1/context
|
|
78
82
|
RESULT=$(curl -s --max-time 3 \
|
|
79
83
|
-X POST \
|
|
@@ -122,9 +126,13 @@ if [ -n "$REMAINING" ]; then
|
|
|
122
126
|
fi
|
|
123
127
|
|
|
124
128
|
if [ -z "$SAAS_COUNT" ] || [ "$SAAS_COUNT" = "0" ]; then
|
|
129
|
+
"$TOAST" memento "✓ No memories matched" &>/dev/null
|
|
125
130
|
exit 0
|
|
126
131
|
fi
|
|
127
132
|
|
|
133
|
+
# Toast: result
|
|
134
|
+
"$TOAST" memento "✓ ${SAAS_COUNT} memories recalled" &>/dev/null
|
|
135
|
+
|
|
128
136
|
# Block the Stop so Claude continues — the reason becomes Claude's next instruction.
|
|
129
137
|
REASON="Autonomous Recall: ${SAAS_COUNT} memories surfaced from your last response.
|
|
130
138
|
${SAAS_DETAIL}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
set -o pipefail
|
|
8
8
|
|
|
9
9
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
10
|
+
TOAST="$SCRIPT_DIR/hook-toast.sh"
|
|
10
11
|
|
|
11
12
|
# --- Config from .memento.json (if present) ---
|
|
12
13
|
CONFIG_JSON=$(python3 -c "
|
|
@@ -66,6 +67,9 @@ fi
|
|
|
66
67
|
|
|
67
68
|
QUERY="${USER_MESSAGE:0:500}"
|
|
68
69
|
|
|
70
|
+
# Toast: start retrieving
|
|
71
|
+
"$TOAST" memento "⏳ Retrieving memories..." &>/dev/null
|
|
72
|
+
|
|
69
73
|
# Call Memento SaaS /v1/context
|
|
70
74
|
SAAS_OUTPUT=$(curl -s --max-time 3 \
|
|
71
75
|
-X POST \
|
|
@@ -118,9 +122,13 @@ if [ -n "$REMAINING" ]; then
|
|
|
118
122
|
fi
|
|
119
123
|
|
|
120
124
|
if [ -z "$SAAS_COUNT" ] || [ "$SAAS_COUNT" = "0" ]; then
|
|
125
|
+
"$TOAST" memento "✓ No memories matched" &>/dev/null
|
|
121
126
|
exit 0
|
|
122
127
|
fi
|
|
123
128
|
|
|
129
|
+
# Toast: result
|
|
130
|
+
"$TOAST" memento "✓ ${SAAS_COUNT} memories recalled" &>/dev/null
|
|
131
|
+
|
|
124
132
|
DETAIL_TEXT="Memento Recall: ${SAAS_COUNT} memories"
|
|
125
133
|
DETAIL_TEXT="$DETAIL_TEXT"$'\n'"$SAAS_DETAIL"
|
|
126
134
|
DETAIL_TEXT="$DETAIL_TEXT"$'\n'$'\n'"REMINDER: If Memento MCP tools are not loaded, run: ToolSearch query=\"+memento\" max_results=20"
|
package/src/cli.js
CHANGED
|
@@ -403,6 +403,7 @@ async function runInit() {
|
|
|
403
403
|
fs.mkdirSync(localScriptsDir, { recursive: true });
|
|
404
404
|
|
|
405
405
|
const scriptFiles = [
|
|
406
|
+
"hook-toast.sh",
|
|
406
407
|
enableUserPrompt && "memento-userprompt-recall.sh",
|
|
407
408
|
enableStop && "memento-stop-recall.sh",
|
|
408
409
|
enablePreCompact && "memento-precompact-distill.sh",
|