@dosx/agent-memory 0.0.13
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/LICENSE +21 -0
- package/README.md +142 -0
- package/bin/agent-memory.js +496 -0
- package/hooks/README.md +292 -0
- package/hooks/agent-memory-hooks/agent-memory-common.sh +1020 -0
- package/hooks/agent-memory-hooks/agent-memory-session.sh +98 -0
- package/hooks/agent-memory-hooks/agent-memory-sync.sh +147 -0
- package/hooks/claude-code/settings.json +51 -0
- package/hooks/codex/config.toml.snippet +38 -0
- package/hooks/codex/hooks.json +51 -0
- package/hooks/copilot/agent-memory.json +34 -0
- package/hooks/cursor/hooks.json +36 -0
- package/hooks/gemini/settings.json +50 -0
- package/hooks/git/pre-commit +45 -0
- package/hooks/install-hooks.sh +358 -0
- package/hooks/opencode/agent-memory.ts +320 -0
- package/package.json +22 -0
- package/skills/agent-memory/SKILL.md +185 -0
- package/skills/agent-memory/references/agent-block.md +115 -0
- package/skills/agent-memory/references/bootstrap.md +84 -0
- package/skills/agent-memory/references/init.md +211 -0
- package/skills/agent-memory/references/install-hooks.md +113 -0
- package/skills/agent-memory/references/lint.md +113 -0
- package/skills/agent-memory/references/sync.md +120 -0
- package/skills/agent-memory/references/update.md +145 -0
- package/skills/agent-memory/vendor/README.md +132 -0
- package/skills/agent-memory/vendor/UPDATE.md +369 -0
- package/skills/agent-memory/vendor/memory/active-work/TEMPLATE.md +33 -0
- package/skills/agent-memory/vendor/memory/current.md +34 -0
- package/skills/agent-memory/vendor/memory/decisions.md +30 -0
- package/skills/agent-memory/vendor/memory/index.md +55 -0
- package/skills/agent-memory/vendor/memory/instructions.md +340 -0
- package/skills/agent-memory/vendor/memory/log.md +38 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# agent-memory sessionStart / NewSession hook — inject context + deterministic
|
|
3
|
+
# memory refresh. Captures session_id from harness stdin JSON when provided.
|
|
4
|
+
# On new session: refresh current.md In progress from active-work/ + log state.
|
|
5
|
+
# No-op when .agents/memory/ is absent.
|
|
6
|
+
#
|
|
7
|
+
# Set AGENT_MEMORY_HOST: cursor | claude | codex | copilot | opencode | gemini
|
|
8
|
+
|
|
9
|
+
set -u
|
|
10
|
+
|
|
11
|
+
host="${AGENT_MEMORY_HOST:-}"
|
|
12
|
+
|
|
13
|
+
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
14
|
+
_common_sh="$script_dir/agent-memory-common.sh"
|
|
15
|
+
if [ ! -f "$_common_sh" ]; then
|
|
16
|
+
printf 'agent-memory: missing agent-memory-common.sh beside %s; install all three hooks/agent-memory-hooks/*.sh together (see hooks/README.md)\n' \
|
|
17
|
+
"$(basename -- "$0")" >&2
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
# shellcheck source=agent-memory-common.sh
|
|
21
|
+
. "$_common_sh"
|
|
22
|
+
|
|
23
|
+
agent_memory_init_context || exit 0
|
|
24
|
+
|
|
25
|
+
[ -d "$memory" ] || exit 0
|
|
26
|
+
|
|
27
|
+
session_id=$(resolve_session_id "$hook_stdin_session_id" 0)
|
|
28
|
+
[ -n "$session_id" ] || write_state current_session_id ""
|
|
29
|
+
persist_session_id "$session_id"
|
|
30
|
+
reset_logged_files_if_session_changed "$session_id" sessionStart
|
|
31
|
+
|
|
32
|
+
# New session: ensure active-work, log heading, current.md in-progress list.
|
|
33
|
+
if command -v git >/dev/null 2>&1 && git -C "$cwd" rev-parse --git-dir >/dev/null 2>&1; then
|
|
34
|
+
refresh_branch_cache
|
|
35
|
+
aw=$(ensure_active_work)
|
|
36
|
+
update_task_stub "$aw"
|
|
37
|
+
ensure_session_log_heading "$session_id" sessionStart
|
|
38
|
+
refresh_current_in_progress
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
msg="Agent Memory (.agents/memory/). Before tasks: read instructions.md, index.md, current.md, and your branch active-work file. As you work: refine active-work Task/Progress, append semantic bullets under the current session heading in log.md, and record every architecture/design decision in decisions.md. Hooks keep Touched files, log file-bullets, and current.md In progress synced — you own task meaning, log type/summary, and decisions.md. Run /agent-memory sync at checkpoints (end of task, before commit/compaction)."
|
|
42
|
+
|
|
43
|
+
json_escape() {
|
|
44
|
+
local s=$1
|
|
45
|
+
s=${s//\\/\\\\}
|
|
46
|
+
s=${s//\"/\\\"}
|
|
47
|
+
s=${s//$'\n'/\\n}
|
|
48
|
+
s=${s//$'\r'/\\r}
|
|
49
|
+
s=${s//$'\t'/\\t}
|
|
50
|
+
printf '%s' "$s"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
case "$host" in
|
|
54
|
+
cursor)
|
|
55
|
+
if [ -n "$session_id" ]; then
|
|
56
|
+
printf '{"env":{"AGENT_MEMORY_SESSION_ID":"%s"},"additional_context":"%s"}\n' \
|
|
57
|
+
"$(json_escape "$session_id")" "$(json_escape "$msg")"
|
|
58
|
+
else
|
|
59
|
+
printf '{"additional_context":"%s"}\n' "$(json_escape "$msg")"
|
|
60
|
+
fi
|
|
61
|
+
;;
|
|
62
|
+
claude)
|
|
63
|
+
if [ -n "$session_id" ]; then
|
|
64
|
+
printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"},"env":{"AGENT_MEMORY_SESSION_ID":"%s"}}\n' \
|
|
65
|
+
"$(json_escape "$msg")" "$(json_escape "$session_id")"
|
|
66
|
+
else
|
|
67
|
+
printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"}}\n' \
|
|
68
|
+
"$(json_escape "$msg")"
|
|
69
|
+
fi
|
|
70
|
+
;;
|
|
71
|
+
codex)
|
|
72
|
+
[ -n "$session_id" ] && export AGENT_MEMORY_SESSION_ID="$session_id"
|
|
73
|
+
printf '%s\n' "$msg"
|
|
74
|
+
;;
|
|
75
|
+
copilot)
|
|
76
|
+
if [ -n "$session_id" ]; then
|
|
77
|
+
printf '{"additionalContext":"%s","env":{"AGENT_MEMORY_SESSION_ID":"%s"}}\n' \
|
|
78
|
+
"$(json_escape "$msg")" "$(json_escape "$session_id")"
|
|
79
|
+
else
|
|
80
|
+
printf '{"additionalContext":"%s"}\n' "$(json_escape "$msg")"
|
|
81
|
+
fi
|
|
82
|
+
;;
|
|
83
|
+
opencode)
|
|
84
|
+
[ -n "$session_id" ] && export AGENT_MEMORY_SESSION_ID="$session_id"
|
|
85
|
+
printf '%s\n' "$msg"
|
|
86
|
+
;;
|
|
87
|
+
gemini)
|
|
88
|
+
# Gemini CLI requires strict JSON-only stdout for hooks (no stray text).
|
|
89
|
+
# We return the memory guidance as context. The deterministic work
|
|
90
|
+
# (heading, current.md, etc.) happens as side effects before this output.
|
|
91
|
+
printf '{"context":"%s"}\n' "$(json_escape "$msg")"
|
|
92
|
+
;;
|
|
93
|
+
*)
|
|
94
|
+
[ -n "$session_id" ] && export AGENT_MEMORY_SESSION_ID="$session_id"
|
|
95
|
+
printf '%s\n' "$msg"
|
|
96
|
+
;;
|
|
97
|
+
esac
|
|
98
|
+
exit 0
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# agent-memory deterministic checkpoint (all harnesses).
|
|
3
|
+
#
|
|
4
|
+
# Evidence-backed updates from git + session ID — no LLM, no invented semantics.
|
|
5
|
+
# Maintains: active-work (Touched files, Task stub), log.md (session heading +
|
|
6
|
+
# file-change bullets on full checkpoints). current.md is refreshed on sessionStart only.
|
|
7
|
+
#
|
|
8
|
+
# Reads harness stdin JSON when present (session_id, cwd, tool_name,
|
|
9
|
+
# tool_input.file_path / tool_input.path / file_path — Claude, Cursor, Copilot,
|
|
10
|
+
# Codex, Gemini). Session ID also from AGENT_MEMORY_SESSION_ID env or state.
|
|
11
|
+
#
|
|
12
|
+
# Set AGENT_MEMORY_EVENT (any host naming):
|
|
13
|
+
# postToolUse | PostToolUse | AfterTool | afterFileEdit
|
|
14
|
+
# — accumulate touched paths from stdin (git-free; no log.md bullets)
|
|
15
|
+
# afterAgentResponse | Stop | agentStop | AfterAgent — end of turn; full git
|
|
16
|
+
# reconciliation (session-cumulative Touched files, log bullets)
|
|
17
|
+
# preCompact | PreCompact | precommit | PreCompress — before compaction or
|
|
18
|
+
# git commit; same as afterAgentResponse
|
|
19
|
+
#
|
|
20
|
+
# Git runs only at afterAgentResponse/preCompact (+ sessionStart in session.sh);
|
|
21
|
+
# postToolUse/afterFileEdit use the branch cache and stdin file path only.
|
|
22
|
+
#
|
|
23
|
+
# Install per host — see hooks/README.md.
|
|
24
|
+
|
|
25
|
+
set -u
|
|
26
|
+
|
|
27
|
+
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
28
|
+
_common_sh="$script_dir/agent-memory-common.sh"
|
|
29
|
+
if [ ! -f "$_common_sh" ]; then
|
|
30
|
+
printf 'agent-memory: missing agent-memory-common.sh beside %s; install all three hooks/agent-memory-hooks/*.sh together (see hooks/README.md)\n' \
|
|
31
|
+
"$(basename -- "$0")" >&2
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
# shellcheck source=agent-memory-common.sh
|
|
35
|
+
. "$_common_sh"
|
|
36
|
+
|
|
37
|
+
raw_event="${AGENT_MEMORY_EVENT:-afterAgentResponse}"
|
|
38
|
+
case "$raw_event" in
|
|
39
|
+
postToolUse|PostToolUse|posttool|AfterTool|aftertool|afterFileEdit|afterfileedit)
|
|
40
|
+
event=postToolUse
|
|
41
|
+
;;
|
|
42
|
+
afterAgentResponse|Stop|stop|agentStop|afterresponse|AfterAgent|afteragent)
|
|
43
|
+
event=afterAgentResponse
|
|
44
|
+
;;
|
|
45
|
+
preCompact|PreCompact|precompact|precommit|PreCompress|precompress)
|
|
46
|
+
event=preCompact
|
|
47
|
+
;;
|
|
48
|
+
*) event=afterAgentResponse ;;
|
|
49
|
+
esac
|
|
50
|
+
|
|
51
|
+
agent_memory_init_context || exit 0
|
|
52
|
+
|
|
53
|
+
[ -d "$memory" ] || exit 0
|
|
54
|
+
command -v git >/dev/null 2>&1 || exit 0
|
|
55
|
+
git -C "$cwd" rev-parse --git-dir >/dev/null 2>&1 || exit 0
|
|
56
|
+
|
|
57
|
+
# Normalize harness file path to a repo-relative path, or return non-zero to skip.
|
|
58
|
+
normalize_repo_rel_path() {
|
|
59
|
+
local rel=$1
|
|
60
|
+
case "$rel" in
|
|
61
|
+
*$'\n'* | *$'\r'* | *$'\x1e'*) return 1 ;;
|
|
62
|
+
esac
|
|
63
|
+
case "$rel" in
|
|
64
|
+
"$cwd"/*) rel=${rel#"$cwd"/} ;;
|
|
65
|
+
/*) return 1 ;;
|
|
66
|
+
esac
|
|
67
|
+
case "$rel" in
|
|
68
|
+
.agents/memory/*) return 1 ;;
|
|
69
|
+
esac
|
|
70
|
+
case "/$rel/" in
|
|
71
|
+
*/../*) return 1 ;;
|
|
72
|
+
esac
|
|
73
|
+
[ -n "$rel" ] || return 1
|
|
74
|
+
printf '%s' "$rel"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
case "$event" in
|
|
78
|
+
postToolUse)
|
|
79
|
+
agent_memory_include_commit_files=0
|
|
80
|
+
[ -n "$hook_stdin_tool_file" ] || exit 0
|
|
81
|
+
run_posttool_checkpoint "$hook_stdin_tool_file"
|
|
82
|
+
exit 0
|
|
83
|
+
;;
|
|
84
|
+
esac
|
|
85
|
+
|
|
86
|
+
session_id=$(resolve_session_id "$hook_stdin_session_id")
|
|
87
|
+
log_session_id=$(normalize_session_id_for_checkpoint "$session_id")
|
|
88
|
+
persist_session_id "$session_id"
|
|
89
|
+
|
|
90
|
+
mark_head_processed() {
|
|
91
|
+
local current_head
|
|
92
|
+
current_head=$(git -C "$cwd" rev-parse HEAD 2>/dev/null || true)
|
|
93
|
+
[ -n "$current_head" ] || return 0
|
|
94
|
+
write_state last_processed_head "$current_head"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Git-free: merge stdin path into session touched set; no log.md bullets.
|
|
98
|
+
run_posttool_checkpoint() {
|
|
99
|
+
local rel=$1 aw accumulated
|
|
100
|
+
rel=$(normalize_repo_rel_path "$rel") || return 0
|
|
101
|
+
accumulated=$(read_state session_touched_files "")
|
|
102
|
+
file_already_logged "$rel" "$accumulated" && return 0
|
|
103
|
+
aw=$(ensure_active_work)
|
|
104
|
+
add_touched_file "$aw" "$rel"
|
|
105
|
+
update_task_stub "$aw"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
run_full_checkpoint() {
|
|
109
|
+
local list_file=$1 aw resolved_sid filtered_tmp
|
|
110
|
+
aw=$(ensure_active_work)
|
|
111
|
+
update_task_stub "$aw"
|
|
112
|
+
resolved_sid=$(ensure_log_heading_for_checkpoint "$log_session_id")
|
|
113
|
+
if [ -s "$list_file" ]; then
|
|
114
|
+
filtered_tmp=$(mktemp)
|
|
115
|
+
while IFS= read -r f || [ -n "$f" ]; do
|
|
116
|
+
[ -n "$f" ] || continue
|
|
117
|
+
f=$(normalize_repo_rel_path "$f") || continue
|
|
118
|
+
printf '%s\n' "$f" >>"$filtered_tmp"
|
|
119
|
+
done <"$list_file"
|
|
120
|
+
if [ -s "$filtered_tmp" ]; then
|
|
121
|
+
update_touched_files "$aw" "$filtered_tmp"
|
|
122
|
+
append_log_file_bullets "$resolved_sid" "$filtered_tmp"
|
|
123
|
+
else
|
|
124
|
+
write_active_work_touched_from_session "$aw"
|
|
125
|
+
fi
|
|
126
|
+
rm -f "$filtered_tmp"
|
|
127
|
+
else
|
|
128
|
+
write_active_work_touched_from_session "$aw"
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case "$event" in
|
|
133
|
+
afterAgentResponse|preCompact)
|
|
134
|
+
agent_memory_include_commit_files=1
|
|
135
|
+
refresh_branch_cache
|
|
136
|
+
list_tmp=$(mktemp)
|
|
137
|
+
list_non_memory_changes >"$list_tmp"
|
|
138
|
+
run_full_checkpoint "$list_tmp"
|
|
139
|
+
rm -f "$list_tmp"
|
|
140
|
+
mark_head_processed
|
|
141
|
+
;;
|
|
142
|
+
*)
|
|
143
|
+
exit 0
|
|
144
|
+
;;
|
|
145
|
+
esac
|
|
146
|
+
|
|
147
|
+
exit 0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "*",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "AGENT_MEMORY_HOST=claude .claude/hooks/agent-memory-session.sh",
|
|
10
|
+
"timeout": 5
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"PostToolUse": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "Write|Edit|Bash",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "AGENT_MEMORY_EVENT=PostToolUse .claude/hooks/agent-memory-sync.sh",
|
|
22
|
+
"timeout": 15
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"Stop": [
|
|
28
|
+
{
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "AGENT_MEMORY_EVENT=Stop .claude/hooks/agent-memory-sync.sh",
|
|
33
|
+
"timeout": 15
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"PreCompact": [
|
|
39
|
+
{
|
|
40
|
+
"matcher": "auto|manual",
|
|
41
|
+
"hooks": [
|
|
42
|
+
{
|
|
43
|
+
"type": "command",
|
|
44
|
+
"command": "AGENT_MEMORY_EVENT=PreCompact .claude/hooks/agent-memory-sync.sh",
|
|
45
|
+
"timeout": 15
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Codex hooks can live in a sidecar hooks.json (see hooks.json) OR inline in
|
|
2
|
+
# config.toml under [hooks]. Inline form (project: .codex/config.toml):
|
|
3
|
+
#
|
|
4
|
+
# [features]
|
|
5
|
+
# hooks = true # enabled by default
|
|
6
|
+
#
|
|
7
|
+
# Copy hooks/agent-memory-hooks/agent-memory-sync.sh and agent-memory-session.sh to
|
|
8
|
+
# .codex/hooks/ first (see hooks/README.md).
|
|
9
|
+
#
|
|
10
|
+
# [[hooks.SessionStart]]
|
|
11
|
+
# matcher = "startup|resume"
|
|
12
|
+
# [[hooks.SessionStart.hooks]]
|
|
13
|
+
# type = "command"
|
|
14
|
+
# command = ["sh", "-c", "AGENT_MEMORY_HOST=codex .codex/hooks/agent-memory-session.sh"]
|
|
15
|
+
# timeout = 5
|
|
16
|
+
#
|
|
17
|
+
# [[hooks.PostToolUse]]
|
|
18
|
+
# matcher = "Bash|apply_patch"
|
|
19
|
+
# [[hooks.PostToolUse.hooks]]
|
|
20
|
+
# type = "command"
|
|
21
|
+
# command = ["sh", "-c", "AGENT_MEMORY_EVENT=PostToolUse .codex/hooks/agent-memory-sync.sh"]
|
|
22
|
+
# timeout = 15
|
|
23
|
+
#
|
|
24
|
+
# [[hooks.Stop]]
|
|
25
|
+
# [[hooks.Stop.hooks]]
|
|
26
|
+
# type = "command"
|
|
27
|
+
# command = ["sh", "-c", "AGENT_MEMORY_EVENT=Stop .codex/hooks/agent-memory-sync.sh"]
|
|
28
|
+
# timeout = 15
|
|
29
|
+
#
|
|
30
|
+
# [[hooks.PreCompact]]
|
|
31
|
+
# matcher = "auto|manual"
|
|
32
|
+
# [[hooks.PreCompact.hooks]]
|
|
33
|
+
# type = "command"
|
|
34
|
+
# command = ["sh", "-c", "AGENT_MEMORY_EVENT=PreCompact .codex/hooks/agent-memory-sync.sh"]
|
|
35
|
+
# timeout = 15
|
|
36
|
+
#
|
|
37
|
+
# After adding project hooks, run `/hooks` in the Codex TUI to trust them.
|
|
38
|
+
# Codex hooks are disabled on Windows.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup|resume",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "AGENT_MEMORY_HOST=codex .codex/hooks/agent-memory-session.sh",
|
|
10
|
+
"timeout": 5
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"PostToolUse": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "Bash|apply_patch",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "AGENT_MEMORY_EVENT=PostToolUse .codex/hooks/agent-memory-sync.sh",
|
|
22
|
+
"timeout": 15
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"Stop": [
|
|
28
|
+
{
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "AGENT_MEMORY_EVENT=Stop .codex/hooks/agent-memory-sync.sh",
|
|
33
|
+
"timeout": 15
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"PreCompact": [
|
|
39
|
+
{
|
|
40
|
+
"matcher": "auto|manual",
|
|
41
|
+
"hooks": [
|
|
42
|
+
{
|
|
43
|
+
"type": "command",
|
|
44
|
+
"command": "AGENT_MEMORY_EVENT=PreCompact .codex/hooks/agent-memory-sync.sh",
|
|
45
|
+
"timeout": 15
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"sessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"type": "command",
|
|
7
|
+
"bash": "AGENT_MEMORY_HOST=copilot .github/hooks/agent-memory-session.sh",
|
|
8
|
+
"timeoutSec": 5
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"postToolUse": [
|
|
12
|
+
{
|
|
13
|
+
"type": "command",
|
|
14
|
+
"bash": "AGENT_MEMORY_EVENT=postToolUse .github/hooks/agent-memory-sync.sh",
|
|
15
|
+
"matcher": "bash|edit|write|apply_patch",
|
|
16
|
+
"timeoutSec": 15
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"agentStop": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"bash": "AGENT_MEMORY_EVENT=agentStop .github/hooks/agent-memory-sync.sh",
|
|
23
|
+
"timeoutSec": 15
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"preCompact": [
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"bash": "AGENT_MEMORY_EVENT=preCompact .github/hooks/agent-memory-sync.sh",
|
|
30
|
+
"timeoutSec": 15
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"hooks": {
|
|
4
|
+
"sessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"command": "AGENT_MEMORY_HOST=cursor .cursor/hooks/agent-memory-session.sh",
|
|
7
|
+
"timeout": 5
|
|
8
|
+
}
|
|
9
|
+
],
|
|
10
|
+
"postToolUse": [
|
|
11
|
+
{
|
|
12
|
+
"command": "AGENT_MEMORY_EVENT=postToolUse .cursor/hooks/agent-memory-sync.sh",
|
|
13
|
+
"matcher": "Write|Shell",
|
|
14
|
+
"timeout": 15
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"afterFileEdit": [
|
|
18
|
+
{
|
|
19
|
+
"command": "AGENT_MEMORY_EVENT=afterFileEdit .cursor/hooks/agent-memory-sync.sh",
|
|
20
|
+
"timeout": 15
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"afterAgentResponse": [
|
|
24
|
+
{
|
|
25
|
+
"command": "AGENT_MEMORY_EVENT=afterAgentResponse .cursor/hooks/agent-memory-sync.sh",
|
|
26
|
+
"timeout": 15
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"preCompact": [
|
|
30
|
+
{
|
|
31
|
+
"command": "AGENT_MEMORY_EVENT=preCompact .cursor/hooks/agent-memory-sync.sh",
|
|
32
|
+
"timeout": 15
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "*",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "AGENT_MEMORY_HOST=gemini .gemini/hooks/agent-memory-session.sh",
|
|
10
|
+
"timeout": 5000
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"AfterTool": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "write_file|edit|shell|bash|apply_patch",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "AGENT_MEMORY_EVENT=AfterTool .gemini/hooks/agent-memory-sync.sh",
|
|
22
|
+
"timeout": 15000
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"AfterAgent": [
|
|
28
|
+
{
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "AGENT_MEMORY_EVENT=AfterAgent .gemini/hooks/agent-memory-sync.sh",
|
|
33
|
+
"timeout": 15000
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"PreCompress": [
|
|
39
|
+
{
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "AGENT_MEMORY_EVENT=PreCompress .gemini/hooks/agent-memory-sync.sh",
|
|
44
|
+
"timeout": 15000
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# agent-memory git pre-commit hook (host-agnostic).
|
|
3
|
+
#
|
|
4
|
+
# Runs the deterministic sync script when co-installed, then reminds when
|
|
5
|
+
# staged work has no .agents/memory/ change (semantic fields may still need
|
|
6
|
+
# /agent-memory sync). Never blocks the commit. Fails open.
|
|
7
|
+
#
|
|
8
|
+
# Install:
|
|
9
|
+
# cp hooks/git/pre-commit .git/hooks/pre-commit
|
|
10
|
+
# cp hooks/agent-memory-hooks/agent-memory-*.sh .git/hooks/
|
|
11
|
+
# chmod +x .git/hooks/pre-commit .git/hooks/agent-memory-*.sh
|
|
12
|
+
|
|
13
|
+
# GIT_PREFIX is the subdirectory where the user ran `git commit`, not the repo
|
|
14
|
+
# root — never use it as PROJECT_DIR (would skip memory when committing from src/).
|
|
15
|
+
cwd=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
|
|
16
|
+
[ -d "$cwd/.agents/memory" ] || exit 0
|
|
17
|
+
|
|
18
|
+
hook_dir=$(dirname "$0")
|
|
19
|
+
if [ -x "$hook_dir/agent-memory-sync.sh" ]; then
|
|
20
|
+
AGENT_MEMORY_EVENT=precommit AGENT_MEMORY_PROJECT_DIR="$cwd" "$hook_dir/agent-memory-sync.sh" || true
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
staged=$(git diff --cached --name-only 2>/dev/null | grep -v '^\.agents/memory/' || true)
|
|
24
|
+
[ -n "$staged" ] || exit 0
|
|
25
|
+
|
|
26
|
+
# Branch sanitization must mirror common.sh:sanitize_branch so the reminder
|
|
27
|
+
# path matches the file ensure_active_work writes. (This hook is /bin/sh and
|
|
28
|
+
# does not source common.sh, so the logic is duplicated by necessity.)
|
|
29
|
+
branch=$(git branch --show-current 2>/dev/null)
|
|
30
|
+
branch=$(printf '%s' "$branch" | tr -c 'A-Za-z0-9._-' '-')
|
|
31
|
+
[ -n "$branch" ] || branch="local"
|
|
32
|
+
|
|
33
|
+
memory_staged=$(git diff --cached --name-only 2>/dev/null | grep '^\.agents/memory/' || true)
|
|
34
|
+
|
|
35
|
+
if [ -z "$memory_staged" ]; then
|
|
36
|
+
cat <<EOF
|
|
37
|
+
|
|
38
|
+
[agent-memory] Staged work on branch '$branch' but no .agents/memory/ change in this commit.
|
|
39
|
+
Hooks updated Touched files from git; review task/progress in
|
|
40
|
+
\`.agents/memory/active-work/$branch.md\` and run \`/agent-memory sync\` if needed.
|
|
41
|
+
(This is a reminder, not a block — the commit will proceed.)
|
|
42
|
+
|
|
43
|
+
EOF
|
|
44
|
+
fi
|
|
45
|
+
exit 0
|