Skip to content

Commit 0f547e6

Browse files
Claudeclaude
authored andcommitted
feat: generate AGENTS.md for IDE-agnostic agent discovery (OD-781)
Init wizard now produces AGENTS.md alongside the IDE-specific instructions file. Contains tool table, core workflow, sub-agent patterns (prepare_context, absorb_observations), and example JSON tool calls. Model-agnostic — no Claude/Cursor-specific references. Idempotent on re-run. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1b1f89a commit 0f547e6

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed

AGENTS.md.template

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# GitMem — Persistent Memory for AI Agents
2+
3+
This project uses [GitMem](https://gitmem.ai), an MCP server that gives agents
4+
persistent memory across sessions. Lessons, mistakes, wins, decisions, and open
5+
threads carry forward — so the same mistake never costs twice.
6+
7+
## MCP Server
8+
9+
GitMem is configured as an MCP server. Check `.mcp.json` or your IDE's MCP
10+
configuration for the server entry. All tools are prefixed `mcp__gitmem__`.
11+
12+
## Tools
13+
14+
| Tool | Purpose |
15+
|------|---------|
16+
| `session_start` | Call at session start — loads context, open threads, recent decisions |
17+
| `session_close` | Call at session end — persists reflection and what was learned |
18+
| `recall` | Before any task — surfaces relevant warnings from past experience |
19+
| `confirm_scars` | After recall — acknowledge each lesson before proceeding |
20+
| `search` | Explore institutional knowledge by topic |
21+
| `log` | Browse recent learnings chronologically |
22+
| `create_learning` | Record a scar (mistake), win (success), or pattern |
23+
| `create_decision` | Log a decision with rationale and alternatives considered |
24+
| `list_threads` | View unresolved work that carries across sessions |
25+
| `create_thread` | Track something needing follow-up in a future session |
26+
| `resolve_thread` | Mark a tracked item as resolved |
27+
| `prepare_context` | Generate a memory payload to inject into sub-agent prompts |
28+
| `absorb_observations` | Ingest findings from sub-agents back into institutional memory |
29+
| `help` | List all available gitmem commands |
30+
31+
## Core Workflow
32+
33+
```
34+
session_start → recall (before tasks) → confirm_scars → work → session_close
35+
```
36+
37+
1. **Start**: `session_start()` — loads last session context and open threads
38+
2. **Recall**: Before consequential actions, call `recall({ plan: "what you're about to do" })`
39+
3. **Confirm**: Address each surfaced scar as `APPLYING`, `N_A`, or `REFUTED`
40+
4. **Work**: Do the task. Create learnings for discoveries worth remembering.
41+
5. **Close**: `session_close({ session_id, close_type: "standard" })`
42+
43+
## Example Tool Calls
44+
45+
### Recall before a task
46+
```json
47+
{
48+
"tool": "mcp__gitmem__recall",
49+
"arguments": {
50+
"plan": "refactor authentication middleware"
51+
}
52+
}
53+
```
54+
55+
### Confirm surfaced scars
56+
```json
57+
{
58+
"tool": "mcp__gitmem__confirm_scars",
59+
"arguments": {
60+
"confirmations": [
61+
{
62+
"scar_id": "abc123",
63+
"decision": "APPLYING",
64+
"evidence": "Verified auth tokens are validated before middleware runs"
65+
}
66+
]
67+
}
68+
}
69+
```
70+
71+
### Create a learning
72+
```json
73+
{
74+
"tool": "mcp__gitmem__create_learning",
75+
"arguments": {
76+
"learning_type": "scar",
77+
"title": "Rate limiter must be initialized before auth middleware",
78+
"description": "If rate limiter loads after auth, unauthenticated requests bypass rate limits entirely.",
79+
"severity": "high",
80+
"counter_arguments": [
81+
"You might think auth should come first since it's more important — but unauthenticated floods can DoS the auth service itself"
82+
]
83+
}
84+
}
85+
```
86+
87+
### Prepare context for a sub-agent
88+
Call before spawning any sub-agent to inject relevant institutional memory into its prompt.
89+
```json
90+
{
91+
"tool": "mcp__gitmem__prepare_context",
92+
"arguments": {
93+
"plan": "review authentication middleware for security issues",
94+
"format": "compact"
95+
}
96+
}
97+
```
98+
The result is a text payload (~500 tokens) you inject into the sub-agent's task prompt. Formats: `compact` (default, one-line per scar), `gate` (~100 tokens, blocking scars only), `full` (rich markdown).
99+
100+
### Absorb observations from sub-agents
101+
After a sub-agent returns, feed its findings back into institutional memory.
102+
```json
103+
{
104+
"tool": "mcp__gitmem__absorb_observations",
105+
"arguments": {
106+
"observations": [
107+
{
108+
"source": "code-review-agent",
109+
"text": "Auth middleware doesn't validate token expiry on refresh endpoints",
110+
"severity": "scar_candidate"
111+
},
112+
{
113+
"source": "code-review-agent",
114+
"text": "Rate limiting is correctly applied before auth checks",
115+
"severity": "info"
116+
}
117+
]
118+
}
119+
}
120+
```
121+
122+
### Sub-agent workflow
123+
```
124+
prepare_context → inject into sub-agent prompt → sub-agent works → absorb_observations
125+
```
126+
127+
## Constraints
128+
129+
- **Recall before acting**: Call `recall()` before tasks that modify code, deploy, or make architectural decisions. Surfaced scars must be confirmed before proceeding.
130+
- **Credential safety**: Never read `.env`, API keys, or credential files in full. Use existence checks only.
131+
- **Session bookends**: Start and close every session. The close reflection is how institutional memory grows.
132+
133+
## Local State
134+
135+
GitMem stores local state in `.gitmem/` (gitignored):
136+
- `config.json` — project configuration
137+
- `sessions/` — session recordings
138+
- `threads.json` — open thread tracking
139+
- `hooks/` — automation scripts (if configured)

bin/init-wizard.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,51 @@ async function stepGitignore() {
879879
return { done: true };
880880
}
881881

882+
async function stepAgentsMd() {
883+
const agentsPath = join(cwd, "AGENTS.md");
884+
const templatePath = join(__dirname, "..", "AGENTS.md.template");
885+
886+
// Already exists — don't overwrite
887+
if (existsSync(agentsPath)) {
888+
const content = readFileSync(agentsPath, "utf-8");
889+
if (content.includes("GitMem")) {
890+
log(CHECK, `AGENTS.md already includes gitmem`);
891+
return { done: false };
892+
}
893+
// Existing AGENTS.md without gitmem — ask before appending
894+
if (interactive) {
895+
if (!(await confirm("Add gitmem section to existing AGENTS.md?"))) {
896+
log(SKIP, "AGENTS.md skipped");
897+
return { done: false };
898+
}
899+
}
900+
}
901+
902+
let template;
903+
try {
904+
template = readFileSync(templatePath, "utf-8");
905+
} catch {
906+
// Template not found — skip silently
907+
return { done: false };
908+
}
909+
910+
if (dryRun) {
911+
log(CHECK, `Would ${existsSync(agentsPath) ? "update" : "create"} AGENTS.md`, "[dry-run]");
912+
return { done: true };
913+
}
914+
915+
if (existsSync(agentsPath)) {
916+
const existing = readFileSync(agentsPath, "utf-8");
917+
writeFileSync(agentsPath, existing.trimEnd() + "\n\n" + template + "\n");
918+
log(CHECK, "Updated AGENTS.md", "Added gitmem section (your existing content is preserved)");
919+
} else {
920+
writeFileSync(agentsPath, template + "\n");
921+
log(CHECK, "Created AGENTS.md", "IDE-agnostic agent discovery file");
922+
}
923+
924+
return { done: true };
925+
}
926+
882927
async function stepFeedbackOptIn() {
883928
const configPath = join(gitmemDir, "config.json");
884929
const config = readJson(configPath) || {};
@@ -980,6 +1025,9 @@ async function main() {
9801025
const r6 = await stepGitignore();
9811026
if (r6.done) configured++;
9821027

1028+
const r6b = await stepAgentsMd();
1029+
if (r6b.done) configured++;
1030+
9831031
const r7 = await stepFeedbackOptIn();
9841032
if (r7.done) configured++;
9851033

0 commit comments

Comments
 (0)