-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfile_changed.sh
More file actions
executable file
·108 lines (90 loc) · 3.03 KB
/
file_changed.sh
File metadata and controls
executable file
·108 lines (90 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/bin/bash
# FileChanged hook: flag stale memories when key config files change
# Watches: .env, docker-compose.yml, package.json, requirements.txt, pyproject.toml
# Tags affected memories with stale_config so hygiene can clean them
INPUT=$(cat 2>/dev/null)
/usr/bin/python3 -W ignore - "$INPUT" 2>/dev/null <<'PYEOF'
import sys, json, os, time, warnings
warnings.filterwarnings("ignore")
os.environ["OMP_NUM_THREADS"] = "2"
os.environ["ONNXRUNTIME_SESSION_THREAD_POOL_SIZE"] = "2"
os.environ["TOKENIZERS_PARALLELISM"] = "false"
raw = sys.argv[1] if len(sys.argv) > 1 else ""
try:
d = json.loads(raw)
except:
sys.exit(0)
changed_file = d.get("file_path", "") or d.get("path", "")
cwd = d.get("cwd", "")
if not changed_file:
sys.exit(0)
basename = os.path.basename(changed_file)
# Only care about config files that affect project setup
CONFIG_FILES = {
".env", ".env.local", ".env.production",
"docker-compose.yml", "docker-compose.yaml",
"package.json", "requirements.txt", "pyproject.toml",
"Dockerfile", "Makefile", "tsconfig.json",
"alembic.ini", ".envrc",
}
if basename not in CONFIG_FILES:
sys.exit(0)
# Find project name from cwd
project_name = ""
if cwd:
parts = cwd.rstrip("/").split("/")
skip = {"home", "Users", "projects", "src", "work", "dev", "repos", "code", ".claude", ""}
for p in reversed(parts):
if p not in skip:
project_name = p
break
if not project_name:
sys.exit(0)
# Search for reference memories in this project that might be stale
sys.path.insert(0, os.path.expanduser("~/.claude/skills/cortex/lib"))
try:
from chroma_client import get_collection
col = get_collection()
if col.count() == 0:
sys.exit(0)
except:
sys.exit(0)
# Search for memories referencing this config file or its contents
query = f"{basename} {project_name} configuration setup"
try:
results = col.query(
query_texts=[query],
n_results=min(5, col.count()),
where={"project": project_name},
)
except:
sys.exit(0)
tagged = 0
for i in range(len(results["ids"][0])):
mid = results["ids"][0][i]
dist = results["distances"][0][i] if results.get("distances") else 1.0
meta = results["metadatas"][0][i]
# Only flag close matches that are reference type
if dist > 0.5 or meta.get("type", "") != "reference":
continue
# Tag with stale_config
existing_tags = meta.get("tags", "")
if "stale_config" in existing_tags:
continue
new_tags = f"{existing_tags},stale_config" if existing_tags else "stale_config"
try:
col.update(ids=[mid], metadatas=[{**meta, "tags": new_tags}])
tagged += 1
except:
pass
if tagged > 0:
context = f"[cortex] {basename} changed — flagged {tagged} reference memory(ies) as potentially stale. Verify they're still accurate."
output = json.dumps({
"suppressOutput": True,
"hookSpecificOutput": {
"hookEventName": "FileChanged",
"additionalContext": context
}
})
print(output)
PYEOF