@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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -0
  3. package/bin/agent-memory.js +496 -0
  4. package/hooks/README.md +292 -0
  5. package/hooks/agent-memory-hooks/agent-memory-common.sh +1020 -0
  6. package/hooks/agent-memory-hooks/agent-memory-session.sh +98 -0
  7. package/hooks/agent-memory-hooks/agent-memory-sync.sh +147 -0
  8. package/hooks/claude-code/settings.json +51 -0
  9. package/hooks/codex/config.toml.snippet +38 -0
  10. package/hooks/codex/hooks.json +51 -0
  11. package/hooks/copilot/agent-memory.json +34 -0
  12. package/hooks/cursor/hooks.json +36 -0
  13. package/hooks/gemini/settings.json +50 -0
  14. package/hooks/git/pre-commit +45 -0
  15. package/hooks/install-hooks.sh +358 -0
  16. package/hooks/opencode/agent-memory.ts +320 -0
  17. package/package.json +22 -0
  18. package/skills/agent-memory/SKILL.md +185 -0
  19. package/skills/agent-memory/references/agent-block.md +115 -0
  20. package/skills/agent-memory/references/bootstrap.md +84 -0
  21. package/skills/agent-memory/references/init.md +211 -0
  22. package/skills/agent-memory/references/install-hooks.md +113 -0
  23. package/skills/agent-memory/references/lint.md +113 -0
  24. package/skills/agent-memory/references/sync.md +120 -0
  25. package/skills/agent-memory/references/update.md +145 -0
  26. package/skills/agent-memory/vendor/README.md +132 -0
  27. package/skills/agent-memory/vendor/UPDATE.md +369 -0
  28. package/skills/agent-memory/vendor/memory/active-work/TEMPLATE.md +33 -0
  29. package/skills/agent-memory/vendor/memory/current.md +34 -0
  30. package/skills/agent-memory/vendor/memory/decisions.md +30 -0
  31. package/skills/agent-memory/vendor/memory/index.md +55 -0
  32. package/skills/agent-memory/vendor/memory/instructions.md +340 -0
  33. package/skills/agent-memory/vendor/memory/log.md +38 -0
@@ -0,0 +1,292 @@
1
+ # agent-memory — agent hooks (optional)
2
+
3
+ Optional hooks that keep agent-memory current during real work. They run a
4
+ **deterministic git checkpoint** — no LLM call, no `followup_message` loops:
5
+
6
+ - **`sessionStart` / NewSession** — session ID, `current.md` _In progress_ from
7
+ `active-work/`, ensure active-work file + `log.md` session heading
8
+ - **`postToolUse` / `afterFileEdit` (Cursor)** — accumulate _Touched files_ from
9
+ harness stdin paths (git-free; no `log.md` bullets)
10
+ - **`afterAgentResponse` / end-of-turn / compact / pre-commit** — full git
11
+ reconciliation: session-cumulative _Touched files_ + new file bullets under
12
+ the current `log.md` session heading
13
+
14
+ **Still manual (agent or `/agent-memory sync`):** semantic `log.md` bullets and
15
+ summary/type, `decisions.md` (required when decisions change), active-work
16
+ Progress/Blockers/Notes, `current.md` _Done_ / _Next steps_, `index.md` lazy
17
+ links, `architecture.md`, `patterns.md`, `vision.md` (ask user if uncertain).
18
+
19
+ ## TL;DR
20
+
21
+ Install with the user-run installer (review first):
22
+
23
+ ```bash
24
+ npx @dosx/agent-memory install hooks <harness>
25
+ # or: bash hooks/install-hooks.sh <harness>
26
+ ```
27
+
28
+ The installer creates the harness directory (e.g. `.cursor/`) if it is missing.
29
+ It refuses destination or parent-directory symlinks and requires an existing
30
+ `PROJECT_DIR` (resolved with `realpath`). Set `AGENT_MEMORY_PROJECT_DIR` to
31
+ install into a project other than the current working directory.
32
+
33
+ | Host | Scripts | Config |
34
+ | --------------- | ----------------------------------------------------------------------- | --------------------------------------- |
35
+ | **Any agent** | `hooks/agent-memory-hooks/*.sh` → `.git/hooks/` (with `git/pre-commit`) | `hooks/git/pre-commit` |
36
+ | **Cursor** | → `.cursor/hooks/` | merge `hooks/cursor/hooks.json` |
37
+ | **Claude Code** | → `.claude/hooks/` | merge `hooks/claude-code/settings.json` |
38
+ | **Codex** | → `.codex/hooks/` | merge `hooks/codex/hooks.json` |
39
+ | **Copilot** | → `.github/hooks/` | `hooks/copilot/agent-memory.json` |
40
+ | **OpenCode** | plugin → `.opencode/hooks/*.sh` | `.opencode/plugin/agent-memory.ts` |
41
+ | **Gemini CLI** | → `.gemini/hooks/` | merge `.gemini/settings.json` |
42
+
43
+ `/agent-memory init <harness>` wires the **context** layer when the harness
44
+ directory already exists; it **prints** hook-install commands and does not copy
45
+ scripts.
46
+
47
+ **Cursor:** `init cursor` wires `.cursor/rules/agent-memory.mdc`
48
+ (`alwaysApply: true`) as the **context layer**. Install hooks separately as the
49
+ **checkpoint layer**. `@import` in `AGENTS.md` is a no-op and `AGENTS.md` may
50
+ not auto-inject, so the `.mdc` is the reliable context path. See root
51
+ `README.md`.
52
+
53
+ ## Events (all hosts)
54
+
55
+ | Checkpoint | Cursor | Claude / Codex | Copilot | Gemini CLI | OpenCode |
56
+ | -------------- | ----------------------------- | -------------- | -------------- | -------------- | -------------- |
57
+ | Session start | `sessionStart` | `SessionStart` | `sessionStart` | `SessionStart` | — |
58
+ | After Write | `postToolUse` (`Write`) | `PostToolUse` | `postToolUse` | `AfterTool` | — |
59
+ | After Edit | `afterFileEdit` | `PostToolUse` | `postToolUse` | `AfterTool` | — |
60
+ | End of turn | `afterAgentResponse` | `Stop` | `agentStop` | `AfterAgent` | `session.idle` |
61
+ | Before compact | `preCompact` | `PreCompact` | `preCompact` | `PreCompress` | `compacting` |
62
+ | Git commit | `precommit` (pre-commit hook) | same | same | same | same |
63
+
64
+ **Cursor `postToolUse` matchers** (per
65
+ [Cursor hooks docs](https://cursor.com/docs/hooks)): `Write`, `Shell`. Agent
66
+ **edits** (StrReplace) fire **`afterFileEdit`** instead — top-level `file_path`
67
+ on stdin, not `tool_input.file_path`.
68
+
69
+ **Copilot / Gemini matchers:** `edit`, `write`, `apply_patch` (Copilot);
70
+ `write_file`, `edit`, `shell`, `bash`, `apply_patch` (Gemini). Copilot may send
71
+ `tool_input.path` instead of `file_path` — parsed by shared helpers.
72
+
73
+ **Codex:** `PostToolUse` matches `Bash|apply_patch` only; file paths from
74
+ `apply_patch` may be absent on stdin — end-of-turn git reconciliation covers
75
+ gaps.
76
+
77
+ **Not used on Cursor:** `stop` + `followup_message` (always starts another LLM
78
+ turn).
79
+
80
+ ## Layout
81
+
82
+ ```text
83
+ hooks/
84
+ ├── install-hooks.sh # user-run installer (also used by npx CLI)
85
+ ├── agent-memory-hooks/
86
+ │ ├── agent-memory-common.sh # shared helpers (sourced by sync + session)
87
+ │ ├── agent-memory-sync.sh # checkpoint after tools / end of turn
88
+ │ └── agent-memory-session.sh # sessionStart / NewSession
89
+ ├── cursor/hooks.json
90
+ ├── claude-code/settings.json
91
+ ├── codex/hooks.json
92
+ ├── codex/config.toml.snippet # manual alternate only — not applied by installer
93
+ ├── copilot/agent-memory.json
94
+ ├── opencode/agent-memory.ts
95
+ ├── gemini/settings.json
96
+ └── git/pre-commit
97
+ ```
98
+
99
+ ## Requirements
100
+
101
+ - `git` on `$PATH`
102
+ - POSIX `sh` / `bash` for command hooks
103
+ - OpenCode: Bun plugin loader
104
+
105
+ ## Install (per project)
106
+
107
+ **Preferred:** run the installer from the project root (needs Node for JSON
108
+ merges):
109
+
110
+ ```bash
111
+ npx @dosx/agent-memory install hooks cursor
112
+ ```
113
+
114
+ Or from a checkout of the same tag:
115
+
116
+ ```bash
117
+ bash hooks/install-hooks.sh cursor
118
+ ```
119
+
120
+ The installer copies **all three** files from `hooks/agent-memory-hooks/` into
121
+ the harness hooks directory (`agent-memory-common.sh` must sit beside the other
122
+ two — sync/session source it). **Never copy only sync + session** — partial
123
+ installs fail at runtime (sync/session print a stderr hint and exit 0 so the
124
+ harness is not blocked). Re-run the installer when hook scripts change.
125
+
126
+ Manual copy examples (if you prefer not to use the installer):
127
+
128
+ ### Cursor (recommended)
129
+
130
+ ```bash
131
+ mkdir -p .cursor/hooks
132
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .cursor/hooks/
133
+ chmod +x .cursor/hooks/agent-memory-*.sh
134
+ # merge hooks/cursor/hooks.json into .cursor/hooks.json
135
+ ```
136
+
137
+ ### Claude Code
138
+
139
+ ```bash
140
+ mkdir -p .claude/hooks
141
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .claude/hooks/
142
+ chmod +x .claude/hooks/agent-memory-*.sh
143
+ # merge hooks/claude-code/settings.json into .claude/settings.json
144
+ ```
145
+
146
+ ### Codex
147
+
148
+ ```bash
149
+ mkdir -p .codex/hooks
150
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .codex/hooks/
151
+ chmod +x .codex/hooks/agent-memory-*.sh
152
+ # merge hooks/codex/hooks.json into .codex/hooks.json
153
+ # then run /hooks in the Codex TUI to trust project hooks
154
+ ```
155
+
156
+ `codex/config.toml.snippet` is a **manual alternate** for TOML-based wiring —
157
+ the installer only merges `hooks/codex/hooks.json` and does not apply the
158
+ snippet.
159
+
160
+ ### Copilot (CLI + cloud agent)
161
+
162
+ ```bash
163
+ mkdir -p .github/hooks
164
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .github/hooks/
165
+ chmod +x .github/hooks/agent-memory-*.sh
166
+ cp hooks/copilot/agent-memory.json .github/hooks/agent-memory.json
167
+ ```
168
+
169
+ ### OpenCode
170
+
171
+ ```bash
172
+ mkdir -p .opencode/hooks .opencode/plugin
173
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .opencode/hooks/
174
+ chmod +x .opencode/hooks/agent-memory-*.sh
175
+ cp hooks/opencode/agent-memory.ts .opencode/plugin/agent-memory.ts
176
+ ```
177
+
178
+ The TypeScript plugin spawns the same shell scripts on `session.idle` and
179
+ `experimental.session.compacting` — see [OpenCode vs hooks](#opencode-vs-hooks)
180
+ below.
181
+
182
+ ### Git (host-agnostic baseline)
183
+
184
+ ```bash
185
+ cp hooks/git/pre-commit .git/hooks/pre-commit
186
+ cp hooks/agent-memory-hooks/agent-memory-*.sh .git/hooks/
187
+ chmod +x .git/hooks/pre-commit .git/hooks/agent-memory-*.sh
188
+ ```
189
+
190
+ ## Verifying
191
+
192
+ - Cursor: **Hooks** settings tab / **Hooks** output channel; restart if needed.
193
+ - Claude Code: `/hooks` shows configured hooks.
194
+ - Codex: `/hooks` in the TUI to inspect and trust.
195
+ - OpenCode: plugin loads at startup; sync script must exist at
196
+ `.opencode/hooks/`.
197
+ - Git: `sh .git/hooks/pre-commit` with staged non-memory changes.
198
+
199
+ ## Safe write scope
200
+
201
+ Canonical **memory contract** (hooks vs agent, all harnesses): `instructions.md`
202
+ → _Harness parity — memory contract_. The table below is a summary; do not drift
203
+ from the contract.
204
+
205
+ | Field | Hook updates? |
206
+ | ----------------------------- | -------------------------------------------- |
207
+ | `active-work` → Touched files | Yes (session-cumulative; git + stdin paths) |
208
+ | `active-work` → Task stub | Yes (from branch name when placeholder) |
209
+ | `log.md` → session heading | Yes (session start or first checkpoint) |
210
+ | `log.md` → file bullets | Yes (full checkpoints only — from `git`) |
211
+ | `log.md` → semantic bullets | **No** — agent or `/agent-memory sync` |
212
+ | `current.md` → In progress | Yes (on session start from `active-work/`) |
213
+ | `current.md` → Done / Next | **No** — agent or `/agent-memory sync` |
214
+ | `decisions.md` | **No** — agent (required on decision change) |
215
+ | `.hook-sync-state` | Yes (session ID, logged/touched paths, etc.) |
216
+
217
+ ### Log format
218
+
219
+ One heading per session; hooks + agent append bullets:
220
+
221
+ ```md
222
+ ## [2026-06-30] [effad5d5-…] [chore] session work
223
+
224
+ - changed 12 files (see active-work Touched files)
225
+ - fixed rate-limit edge case in auth middleware
226
+ ```
227
+
228
+ When more than eight new paths land in one full checkpoint, hooks write the
229
+ summary line above instead of individual ``- `path` `` bullets. Semantic context
230
+ always comes from the agent. After a summary, later small batches in the same
231
+ session do not append stray path-only bullets.
232
+
233
+ Session ID from `AGENT_MEMORY_SESSION_ID` (set by `agent-memory-session.sh` when
234
+ the harness sends `session_id` on stdin). See `instructions.md` and `log.md`.
235
+
236
+ State is tracked in `.agents/memory/.hook-sync-state`. Listed in the skeleton
237
+ `.gitignore` and should not be committed.
238
+
239
+ ## Harness-agnostic resolution
240
+
241
+ Scripts never assume a single harness. Shared helpers in
242
+ `agent-memory-common.sh` resolve context in this order:
243
+
244
+ **Project directory** (`resolve_project_dir`):
245
+
246
+ 1. `AGENT_MEMORY_PROJECT_DIR` (generic — git pre-commit, OpenCode plugin)
247
+ 2. `CURSOR_PROJECT_DIR` (Cursor hooks)
248
+ 3. `CLAUDE_PROJECT_DIR` (Claude Code hooks)
249
+ 4. `CODEX_PROJECT_DIR` (Codex hooks)
250
+ 5. `GITHUB_WORKSPACE` (CI / Copilot cloud)
251
+ 6. `GEMINI_PROJECT_DIR` (Gemini CLI)
252
+ 7. `cwd` or `workspace_roots[0]` from hook stdin JSON
253
+ 8. `$PWD`
254
+
255
+ **Session ID** (`resolve_session_id`):
256
+
257
+ 1. `AGENT_MEMORY_SESSION_ID` — set by `sessionStart` via hook `env` output
258
+ (Cursor, Claude, Copilot) or export (Codex, OpenCode plugin)
259
+ 2. `CURSOR_SESSION_ID` — interop fallback (not Cursor-native; third-party hooks
260
+ may export it via sessionStart env output)
261
+ 3. `GEMINI_SESSION_ID` (Gemini CLI)
262
+ 4. `session_id`, `conversation_id`, or `sessionId` from hook stdin JSON (Cursor,
263
+ Claude, Copilot, Codex, Gemini on every lifecycle event)
264
+ 5. `current_session_id` in `.hook-sync-state` (last sessionStart)
265
+
266
+ Cursor `afterAgentResponse` omits `session_id` on stdin — sync relies on (1) or
267
+ (4). Claude `PostToolUse` / `Stop` include `session_id` on stdin — sync parses
268
+ it on every run.
269
+
270
+ ## OpenCode vs hooks
271
+
272
+ OpenCode does **not** use `hooks.json`. The Bun plugin
273
+ (`.opencode/plugin/agent-memory.ts`) is a thin adapter that spawns the same
274
+ shell scripts:
275
+
276
+ | OpenCode plugin event | Spawns | Maps to |
277
+ | --------------------------------- | --------------------------- | ------------ |
278
+ | First `session.idle` of the day | `agent-memory-session.sh` | sessionStart |
279
+ | `session.idle` (later same day) | `agent-memory-sync.sh` only | end of turn |
280
+ | `experimental.session.compacting` | `agent-memory-sync.sh` only | `PreCompact` |
281
+
282
+ **OpenCode log headings:** OpenCode emits a new `ses_*` session ID on many idle
283
+ and compaction events. Shell helpers bind **one `log.md` heading per calendar
284
+ day** (`opencode_log_heading_id` in `.hook-sync-state`) instead of one heading
285
+ per `ses_*`. Empty duplicate `ses_*` headings are pruned on sessionStart.
286
+ Semantic bullets remain agent-owned (`/agent-memory sync`).
287
+
288
+ Logic lives in the shared `.sh` files; the plugin only passes an **allowlisted**
289
+ environment (`PATH` / `HOME` / `TMP*` / `LANG` / `LC_*` / `TZ` plus
290
+ `AGENT_MEMORY_HOST` / `EVENT` / `PROJECT_DIR` / `SESSION_ID`),
291
+ `AGENT_MEMORY_SESSION_ID`, and minimal stdin JSON. Install all three scripts
292
+ under `.opencode/hooks/`.