create-egregore 0.21.0-runtime-mvp.18 → 0.21.0-runtime-mvp.20
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/assets/egregore-launcher.js +2 -2
- package/package.json +1 -1
- package/runtime/claude/.claude/hooks/memory-read-guard.sh +69 -0
- package/runtime/claude/.claude/hooks/retrieval-context.sh +3 -0
- package/runtime/claude/.claude/settings.json +9 -0
- package/runtime/claude/bin/search.sh +5 -0
- package/runtime/claude/manifest.json +1 -0
- package/runtime/codex/bin/search.sh +5 -0
- package/runtime/pi/bin/search.sh +5 -0
- package/runtime/prime/bin/search.sh +5 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// egregore-launcher-version: 0.21.0-runtime-mvp.
|
|
2
|
+
// egregore-launcher-version: 0.21.0-runtime-mvp.20
|
|
3
3
|
//
|
|
4
4
|
// egregore — launch and browse Egregore instances from your terminal.
|
|
5
5
|
// Installed by create-egregore. Reads ~/.egregore/instances.json.
|
|
@@ -35,7 +35,7 @@ const crypto = require("node:crypto");
|
|
|
35
35
|
const { spawnSync, spawn } = require("node:child_process");
|
|
36
36
|
const readline = require("node:readline");
|
|
37
37
|
|
|
38
|
-
const VERSION = "0.21.0-runtime-mvp.
|
|
38
|
+
const VERSION = "0.21.0-runtime-mvp.20";
|
|
39
39
|
const REGISTRY = path.join(os.homedir(), ".egregore", "instances.json");
|
|
40
40
|
const DEFAULT_FILE = path.join(os.homedir(), ".egregore", "default");
|
|
41
41
|
const UPDATE_CACHE_FILE = path.join(os.homedir(), ".egregore", "update-check.json");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-egregore",
|
|
3
|
-
"version": "0.21.0-runtime-mvp.
|
|
3
|
+
"version": "0.21.0-runtime-mvp.20",
|
|
4
4
|
"description": "Set up Egregore for your team in one command — installs the egregore launcher and your choice of Claude Code, Codex, or Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# memory-read-guard.sh — PreToolUse hook for Read and Bash.
|
|
3
|
+
#
|
|
4
|
+
# After a Runtime retrieval, memory sources are opened through the private
|
|
5
|
+
# evidence packet — `bash bin/search.sh open <path> --context-packet` — and
|
|
6
|
+
# never dumped into the transcript with cat/sed/head/tail or the Read tool.
|
|
7
|
+
# Instructions alone did not hold (2026-09-03: three `sed -n 1,140p` dumps of
|
|
8
|
+
# memory files right after a clean search), so this hook enforces it.
|
|
9
|
+
#
|
|
10
|
+
# Scope: a retrieval episode. The guard engages only while this session's
|
|
11
|
+
# retrieval episode is fresh (a search or open within the last
|
|
12
|
+
# EGREGORE_RETRIEVAL_WINDOW_MIN minutes, default 15). Outside an episode — editing a decision record, a skill
|
|
13
|
+
# reading memory, ordinary work — memory reads are untouched. Edit and Write
|
|
14
|
+
# are never the guard's business. Searching memory with grep passes.
|
|
15
|
+
#
|
|
16
|
+
# Exit 0 = allow, exit 2 = block (reason on stderr). Any unexpected failure
|
|
17
|
+
# falls through to allow; the hook must never block by crashing.
|
|
18
|
+
set -u
|
|
19
|
+
|
|
20
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(cd "$(dirname "$0")/../.." && pwd)}"
|
|
21
|
+
[ -d "$PROJECT_DIR" ] || exit 0
|
|
22
|
+
INPUT=$(cat 2>/dev/null) || exit 0
|
|
23
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
24
|
+
case "$TOOL" in Bash|Read) ;; *) exit 0 ;; esac
|
|
25
|
+
|
|
26
|
+
# --- Retrieval episode: this session's packet exists and is fresh ---------
|
|
27
|
+
SESSION=$(cat "$PROJECT_DIR/.egregore-session-id" 2>/dev/null | tr -cd 'A-Za-z0-9_.-')
|
|
28
|
+
[ -n "$SESSION" ] || exit 0
|
|
29
|
+
# The packet itself is consumed by the PostToolUse hook the moment it is
|
|
30
|
+
# attached, so the episode is recorded by a marker that bin/search.sh and the
|
|
31
|
+
# PostToolUse hook both touch. The packet is checked too, for the window
|
|
32
|
+
# between its write and its consumption.
|
|
33
|
+
CTX_DIR="${TMPDIR:-/tmp}/egregore-retrieval-context"
|
|
34
|
+
WINDOW_MIN="${EGREGORE_RETRIEVAL_WINDOW_MIN:-15}"
|
|
35
|
+
_fresh() { [ -f "$1" ] && [ -n "$(find "$1" -mmin "-$WINDOW_MIN" 2>/dev/null)" ]; }
|
|
36
|
+
_fresh "$CTX_DIR/$SESSION.episode" || _fresh "$CTX_DIR/$SESSION.context" || exit 0
|
|
37
|
+
|
|
38
|
+
_block() {
|
|
39
|
+
printf 'Egregore: memory sources are opened through the private evidence packet, not printed into the transcript.\n' >&2
|
|
40
|
+
printf 'Run, one file per call:\n bash bin/search.sh open %s --context-packet\n' "$1" >&2
|
|
41
|
+
printf 'Searching with grep is fine; dumping a file with cat/sed/head/tail or the Read tool is not.\n' >&2
|
|
42
|
+
exit 2
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if [ "$TOOL" = "Read" ]; then
|
|
46
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
47
|
+
[ -n "$FILE" ] || exit 0
|
|
48
|
+
case "$FILE" in
|
|
49
|
+
"$PROJECT_DIR"/memory/*) _block "memory/${FILE#"$PROJECT_DIR"/memory/}" ;;
|
|
50
|
+
memory/*) _block "$FILE" ;;
|
|
51
|
+
esac
|
|
52
|
+
# The memory symlink's target (the sibling memory repository) counts too.
|
|
53
|
+
MEM_REAL=$(readlink -f "$PROJECT_DIR/memory" 2>/dev/null || true)
|
|
54
|
+
if [ -n "$MEM_REAL" ]; then
|
|
55
|
+
case "$FILE" in "$MEM_REAL"/*) _block "memory/${FILE#"$MEM_REAL"/}" ;; esac
|
|
56
|
+
fi
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# --- Bash: a raw reader applied to a memory path -------------------------
|
|
61
|
+
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
62
|
+
[ -n "$CMD" ] || exit 0
|
|
63
|
+
case "$CMD" in *bin/search.sh*) exit 0 ;; esac
|
|
64
|
+
MEM_PATH=$(printf '%s' "$CMD" | grep -oE 'memory/[A-Za-z0-9_./@:+-]+' | head -1)
|
|
65
|
+
[ -n "$MEM_PATH" ] || exit 0
|
|
66
|
+
if printf '%s' "$CMD" | grep -qE '(^|[;&|(][[:space:]]*)(cat|sed|head|tail|less|more|awk|bat|nl)([[:space:]]|$)'; then
|
|
67
|
+
_block "$MEM_PATH"
|
|
68
|
+
fi
|
|
69
|
+
exit 0
|
|
@@ -39,5 +39,8 @@ jq -Rs '{
|
|
|
39
39
|
)
|
|
40
40
|
}
|
|
41
41
|
}' "$PACKET"
|
|
42
|
+
# The packet is one-shot, but the retrieval episode is not: leave a marker so
|
|
43
|
+
# memory-read-guard.sh keeps routing raw memory reads through the opener.
|
|
44
|
+
touch "${PACKET%.context}.episode" 2>/dev/null || true
|
|
42
45
|
rm -f "$PACKET"
|
|
43
46
|
exit 0
|
|
@@ -56,6 +56,15 @@
|
|
|
56
56
|
}
|
|
57
57
|
]
|
|
58
58
|
},
|
|
59
|
+
{
|
|
60
|
+
"matcher": "Read|Bash",
|
|
61
|
+
"hooks": [
|
|
62
|
+
{
|
|
63
|
+
"type": "command",
|
|
64
|
+
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/memory-read-guard.sh"
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
59
68
|
{
|
|
60
69
|
"matcher": "Edit|Write|Bash|EnterWorktree|EnterPlanMode",
|
|
61
70
|
"hooks": [
|
|
@@ -283,6 +283,10 @@ cmd_query() {
|
|
|
283
283
|
}
|
|
284
284
|
umask 077
|
|
285
285
|
printf '%s\n' "$out" > "$packet"
|
|
286
|
+
# The PostToolUse hook consumes the packet the moment it attaches it; the
|
|
287
|
+
# episode marker outlives that so the memory-read guard knows a retrieval
|
|
288
|
+
# just happened.
|
|
289
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
286
290
|
_banner_and_emit "$label" "$t0" "$emit" "$out" 1
|
|
287
291
|
else
|
|
288
292
|
_banner_and_emit "$label" "$t0" "$emit" "$out"
|
|
@@ -343,6 +347,7 @@ case "${1:-}" in
|
|
|
343
347
|
umask 077
|
|
344
348
|
if _runtime open "$OPEN_PATH" > "$packet" 2>"$packet.err"; then
|
|
345
349
|
rm -f "$packet.err"
|
|
350
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
346
351
|
echo "↳ opened $OPEN_PATH · content attached privately"
|
|
347
352
|
else
|
|
348
353
|
cat "$packet.err" >&2 2>/dev/null
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
".claude/hooks/branch-guard.sh",
|
|
63
63
|
".claude/hooks/card-context.sh",
|
|
64
64
|
".claude/hooks/emissary-detect.sh",
|
|
65
|
+
".claude/hooks/memory-read-guard.sh",
|
|
65
66
|
".claude/hooks/memory-refresh.sh",
|
|
66
67
|
".claude/hooks/onboarding-guard.sh",
|
|
67
68
|
".claude/hooks/retrieval-context.sh",
|
|
@@ -283,6 +283,10 @@ cmd_query() {
|
|
|
283
283
|
}
|
|
284
284
|
umask 077
|
|
285
285
|
printf '%s\n' "$out" > "$packet"
|
|
286
|
+
# The PostToolUse hook consumes the packet the moment it attaches it; the
|
|
287
|
+
# episode marker outlives that so the memory-read guard knows a retrieval
|
|
288
|
+
# just happened.
|
|
289
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
286
290
|
_banner_and_emit "$label" "$t0" "$emit" "$out" 1
|
|
287
291
|
else
|
|
288
292
|
_banner_and_emit "$label" "$t0" "$emit" "$out"
|
|
@@ -343,6 +347,7 @@ case "${1:-}" in
|
|
|
343
347
|
umask 077
|
|
344
348
|
if _runtime open "$OPEN_PATH" > "$packet" 2>"$packet.err"; then
|
|
345
349
|
rm -f "$packet.err"
|
|
350
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
346
351
|
echo "↳ opened $OPEN_PATH · content attached privately"
|
|
347
352
|
else
|
|
348
353
|
cat "$packet.err" >&2 2>/dev/null
|
package/runtime/pi/bin/search.sh
CHANGED
|
@@ -283,6 +283,10 @@ cmd_query() {
|
|
|
283
283
|
}
|
|
284
284
|
umask 077
|
|
285
285
|
printf '%s\n' "$out" > "$packet"
|
|
286
|
+
# The PostToolUse hook consumes the packet the moment it attaches it; the
|
|
287
|
+
# episode marker outlives that so the memory-read guard knows a retrieval
|
|
288
|
+
# just happened.
|
|
289
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
286
290
|
_banner_and_emit "$label" "$t0" "$emit" "$out" 1
|
|
287
291
|
else
|
|
288
292
|
_banner_and_emit "$label" "$t0" "$emit" "$out"
|
|
@@ -343,6 +347,7 @@ case "${1:-}" in
|
|
|
343
347
|
umask 077
|
|
344
348
|
if _runtime open "$OPEN_PATH" > "$packet" 2>"$packet.err"; then
|
|
345
349
|
rm -f "$packet.err"
|
|
350
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
346
351
|
echo "↳ opened $OPEN_PATH · content attached privately"
|
|
347
352
|
else
|
|
348
353
|
cat "$packet.err" >&2 2>/dev/null
|
|
@@ -283,6 +283,10 @@ cmd_query() {
|
|
|
283
283
|
}
|
|
284
284
|
umask 077
|
|
285
285
|
printf '%s\n' "$out" > "$packet"
|
|
286
|
+
# The PostToolUse hook consumes the packet the moment it attaches it; the
|
|
287
|
+
# episode marker outlives that so the memory-read guard knows a retrieval
|
|
288
|
+
# just happened.
|
|
289
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
286
290
|
_banner_and_emit "$label" "$t0" "$emit" "$out" 1
|
|
287
291
|
else
|
|
288
292
|
_banner_and_emit "$label" "$t0" "$emit" "$out"
|
|
@@ -343,6 +347,7 @@ case "${1:-}" in
|
|
|
343
347
|
umask 077
|
|
344
348
|
if _runtime open "$OPEN_PATH" > "$packet" 2>"$packet.err"; then
|
|
345
349
|
rm -f "$packet.err"
|
|
350
|
+
touch "${packet%.context}.episode" 2>/dev/null || true
|
|
346
351
|
echo "↳ opened $OPEN_PATH · content attached privately"
|
|
347
352
|
else
|
|
348
353
|
cat "$packet.err" >&2 2>/dev/null
|