@vuau/agent-memory 0.4.1 → 0.5.1

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/README.md CHANGED
@@ -1,17 +1,12 @@
1
1
  # @vuau/agent-memory
2
2
 
3
- Structured AI memory for codebases. Uses `AGENTS.md` to work with OpenCode, GitHub Copilot, Cursor, Windsurf, and any AI coding assistant that reads markdown files.
3
+ Structured AI memory for codebases. Works with GitHub Copilot, Cursor, Windsurf, and any AI coding assistant that reads markdown files.
4
4
 
5
5
  **[Tiếng Việt →](./README.vi.md)**
6
6
 
7
7
  ## Problem
8
8
 
9
- AI coding assistants lose context between sessions. They can't remember:
10
- - Architecture decisions you made last week
11
- - Code patterns specific to your project
12
- - What task you were working on yesterday
13
-
14
- **agent-memory** solves this with a simple file-based memory system that any AI can read.
9
+ AI coding assistants lose context between sessions. They can't remember architecture decisions, specific code patterns, or current tasks. **agent-memory** solves this with a simple file-based memory system that any AI can read and update.
15
10
 
16
11
  ## Quick Start
17
12
 
@@ -23,8 +18,9 @@ npx @vuau/agent-memory init
23
18
 
24
19
  ```
25
20
  / (Project Root)
26
- ├── AGENTS.md # Root agent rules
21
+ ├── AGENTS.md # Fixed router (managed by package)
27
22
  └── .agents/
23
+ ├── CUSTOM.md # Project-specific rules & spec mapping
28
24
  ├── MEMORY.md # Long-term memory (decisions, patterns)
29
25
  ├── TASKS.md # Working memory (current tasks)
30
26
  └── spec/ # Detailed specs (on-demand)
@@ -32,96 +28,40 @@ npx @vuau/agent-memory init
32
28
 
33
29
  ## How It Works
34
30
 
35
- 1. **You run `init`** → Creates `AGENTS.md` + `.agents/` structure
36
- 2. **Agent reads rules** → Finds documentation map pointing to `.agents/`
37
- 3. **Agent works** → Reads MEMORY.md before implementing, updates TASKS.md
38
- 4. **You approve decision** → Agent writes 1-line entry to MEMORY.md
39
- 5. **Next session** → Agent reads memory, continues where you left off
40
-
41
- **No plugin required.** The rules in `AGENTS.md` instruct the agent what to do.
31
+ 1. **You run `init`** → Creates the structure. `AGENTS.md` points to `.agents/CUSTOM.md`.
32
+ 2. **Agent reads rules** → Follows the priority: CUSTOM.md > AGENTS.md > spec files.
33
+ 3. **Agent works** → Updates MEMORY.md for decisions and TASKS.md for progress.
34
+ 4. **Update package** → Run `agent-memory update` to get the latest `AGENTS.md` router without losing your custom rules.
42
35
 
43
- ## CLI Options
36
+ ## CLI Commands
44
37
 
45
38
  ```bash
46
- npx @vuau/agent-memory init [options]
47
-
48
- Options:
49
- --force Overwrite existing files without asking
50
- --name <n> Project name (default: from package.json)
51
-
52
- npx @vuau/agent-memory doctor # Validate structure
53
- npx @vuau/agent-memory help # Show help
54
- ```
55
-
56
- ## Memory Protocol
57
-
58
- Agents follow this protocol (defined in config files):
59
-
60
- ```markdown
61
- ## When to write
62
- - User approves a decision → append to .agents/MEMORY.md
63
- - Explore codebase/architecture → update .agents/spec/*.md
64
- - Start/finish a large task → update .agents/TASKS.md
65
-
66
- ## Entry format
67
- - YYYY-MM-DD: <1-line decision or pattern>
68
- ```
69
-
70
- ### MEMORY.md Example
71
-
72
- ```markdown
73
- ## Patterns
74
- - 2026-04-24: State files = 3 layers (interfaces → defaults → variants)
75
- - 2026-04-24: Dumb components: initialState prop + optional callbacks
76
-
77
- ## Decisions
78
- - 2026-04-06: Use useMediaQuery over CSS display:none for heavy components
39
+ npx @vuau/agent-memory init # Scaffold .agents/ structure
40
+ npx @vuau/agent-memory update # Update AGENTS.md router to latest version
41
+ npx @vuau/agent-memory doctor # Validate structure integrity
42
+ npx @vuau/agent-memory help # Show help
79
43
  ```
80
44
 
81
45
  ## Architecture
82
46
 
83
- ### 4-Layer Design
84
-
85
- | Layer | File | Purpose |
86
- |-------|------|---------|
87
- | Router | AGENTS.md | Rules + pointers (~100 lines) |
88
- | Memory | .agents/MEMORY.md | Curated decisions (1-line each) |
89
- | Tasks | .agents/TASKS.md | Current work, next steps |
90
- | Specs | .agents/spec/*.md | Detailed docs (on-demand) |
91
-
92
- ### Why File-Based?
93
-
94
- We tested memsearch, qmd, mem0, memories.sh — all failed for various reasons (see [RESEARCH.md](./docs/RESEARCH.md)):
95
-
96
- - **Context Blindness**: Auto-capture can't link user intent to prior analysis
97
- - **Context Bloat**: Fallback to transcripts costs 47k+ tokens
98
- - **Platform issues**: Dependencies don't work on Windows/VM
99
-
100
- File-based solution:
101
- - Agent writes when they understand context (quality > automation)
102
- - Plain markdown (portable, git-versionable, human-readable)
103
- - No dependencies (works everywhere)
47
+ ### The Router Split
104
48
 
105
- ## Cross-IDE Compatibility
49
+ - **AGENTS.md**: Core router managed by the package. Do not edit this file directly as it may be overwritten.
50
+ - **.agents/CUSTOM.md**: Your project's home for custom rules, architectural decisions, and documentation mapping.
106
51
 
107
- By default, we only scaffold `AGENTS.md`, which is an emerging standard router file.
108
-
109
- If your tool requires a specific file (e.g. Cursor requires `.cursorrules`, GitHub Copilot requires `.github/copilot-instructions.md`), you can simply symlink or copy `AGENTS.md`:
110
-
111
- ```bash
112
- # For Cursor
113
- ln -s AGENTS.md .cursorrules
114
-
115
- # For GitHub Copilot
116
- mkdir -p .github && ln -s ../AGENTS.md .github/copilot-instructions.md
117
- ```
52
+ ### Memory Files
118
53
 
119
- All tools will read from the same underlying `.agents/` memory structure.
54
+ | File | Purpose |
55
+ |------|---------|
56
+ | .agents/MEMORY.md | Curated decisions (1-line each) |
57
+ | .agents/TASKS.md | Current work, next steps |
58
+ | .agents/spec/*.md | Detailed technical documentation |
120
59
 
121
- ## Documentation
60
+ ## Why File-Based?
122
61
 
123
- - **[RESEARCH.md](./docs/RESEARCH.md)** Problem, experiments, comparison, why file-based wins
124
- - **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** 4-layer design, scalability, migration
62
+ - **Context Precision**: AI writes when they understand context (quality > automation).
63
+ - **Portable**: Plain markdown is portable, git-versionable, and human-readable.
64
+ - **Minimalist**: No dependencies, no background processes, no API keys.
125
65
 
126
66
  ## License
127
67
 
package/README.vi.md CHANGED
@@ -1,15 +1,12 @@
1
1
  # @vuau/agent-memory
2
2
 
3
- Bộ nhớ AI có cấu trúc cho các codebase. Sử dụng `AGENTS.md` để hoạt động với OpenCode, GitHub Copilot, Cursor, Windsurf, và bất kỳ AI coding assistant nào đọc markdown files.
3
+ Bộ nhớ AI có cấu trúc cho các codebase. Hoạt động với GitHub Copilot, Cursor, Windsurf, và bất kỳ AI coding assistant nào đọc markdown files.
4
4
 
5
- ## Bài toán
5
+ **[English →](./README.md)**
6
6
 
7
- AI coding assistants mất bối cảnh giữa các phiên. Họ không thể nhớ:
8
- - Các quyết định kiến trúc bạn đã đưa ra tuần trước
9
- - Các mẫu thiết kế cụ thể của dự án
10
- - Task bạn đang làm hôm qua
7
+ ## Bài toán
11
8
 
12
- **agent-memory** giải quyết bằng hệ thống bộ nhớ đơn giản dựa trên file mà bất kỳ AI nào cũng có thể đọc.
9
+ AI coding assistants mất bối cảnh giữa các phiên làm việc. Họ không thể nhớ các quyết định kiến trúc, các mẫu thiết kế cụ thể, hoặc các task đang làm dở. **agent-memory** giải quyết vấn đề này bằng một hệ thống bộ nhớ đơn giản dựa trên file mà bất kỳ AI nào cũng có thể đọc và cập nhật.
13
10
 
14
11
  ## Bắt đầu nhanh
15
12
 
@@ -21,105 +18,50 @@ npx @vuau/agent-memory init
21
18
 
22
19
  ```
23
20
  / (Project Root)
24
- ├── AGENTS.md # Root agent rules
21
+ ├── AGENTS.md # Router cố định (quản lý bởi package)
25
22
  └── .agents/
26
- ├── MEMORY.md # Long-term memory (decisions, patterns)
27
- ├── TASKS.md # Working memory (current tasks)
28
- └── spec/ # Detailed specs (on-demand)
23
+ ├── CUSTOM.md # Rules riêng của project & mapping tài liệu
24
+ ├── MEMORY.md # Bộ nhớ dài hạn (quyết định, patterns)
25
+ ├── TASKS.md # Bộ nhớ làm việc (tasks hiện tại)
26
+ └── spec/ # Tài liệu kỹ thuật chi tiết (on-demand)
29
27
  ```
30
28
 
31
29
  ## Cách hoạt động
32
30
 
33
- 1. **Bạn chạy `init`** → Tạo `AGENTS.md` + `.agents/` structure
34
- 2. **Agent đọc rules** → Tìm documentation map trỏ đến `.agents/`
35
- 3. **Agent làm việc** → Đọc MEMORY.md trước khi implement, update TASKS.md
36
- 4. **Bạn approve decision** → Agent ghi 1-line entry vào MEMORY.md
37
- 5. **Phiên tiếp theo** → Agent đọc memory, tiếp tục từ nơi dừng lại
38
-
39
- **Không cần plugin.** Rules trong `AGENTS.md` hướng dẫn agent phải làm gì.
31
+ 1. **Bạn chạy `init`** → Tạo cấu trúc thư mục. `AGENTS.md` sẽ trỏ đến `.agents/CUSTOM.md`.
32
+ 2. **Agent đọc rules** → Tuân theo ưu tiên: CUSTOM.md > AGENTS.md > spec files.
33
+ 3. **Agent làm việc** → Cập nhật MEMORY.md cho các quyết định TASKS.md cho tiến độ công việc.
34
+ 4. **Cập nhật package** → Chạy `agent-memory update` để nhận router `AGENTS.md` mới nhất mà không mất các rules tùy chỉnh của bạn.
40
35
 
41
- ## CLI Options
36
+ ## Các lệnh CLI
42
37
 
43
38
  ```bash
44
- npx @vuau/agent-memory init [options]
45
-
46
- Options:
47
- --force Ghi đè files sẵn mà không hỏi
48
- --name <n> Tên project (mặc định: từ package.json)
49
-
50
- npx @vuau/agent-memory doctor # Validate structure
51
- npx @vuau/agent-memory help # Hiện help
52
- ```
53
-
54
- ## Memory Protocol
55
-
56
- Agents follow protocol này (defined trong config files):
57
-
58
- ```markdown
59
- ## Khi nào ghi
60
- - User approves decision → append vào .agents/MEMORY.md
61
- - Explore codebase/architecture → update .agents/spec/*.md
62
- - Start/finish large task → update .agents/TASKS.md
63
-
64
- ## Entry format
65
- - YYYY-MM-DD: <1-line decision hoặc pattern>
66
- ```
67
-
68
- ### MEMORY.md Ví dụ
69
-
70
- ```markdown
71
- ## Patterns
72
- - 2026-04-24: State files = 3 layers (interfaces → defaults → variants)
73
- - 2026-04-24: Dumb components: initialState prop + optional callbacks
74
-
75
- ## Decisions
76
- - 2026-04-06: Use useMediaQuery over CSS display:none cho heavy components
39
+ npx @vuau/agent-memory init # Khởi tạo cấu trúc .agents/
40
+ npx @vuau/agent-memory update # Cập nhật router AGENTS.md lên bản mới nhất
41
+ npx @vuau/agent-memory doctor # Kiểm tra tính toàn vẹn của cấu trúc
42
+ npx @vuau/agent-memory help # Hiện trợ giúp
77
43
  ```
78
44
 
79
45
  ## Kiến trúc
80
46
 
81
- ### Thiết kế 4-Layer
82
-
83
- | Layer | File | Mục đích |
84
- |-------|------|----------|
85
- | Router | AGENTS.md | Rules + pointers (~100 dòng) |
86
- | Memory | .agents/MEMORY.md | Curated decisions (1-line each) |
87
- | Tasks | .agents/TASKS.md | Current work, next steps |
88
- | Specs | .agents/spec/*.md | Detailed docs (on-demand) |
89
-
90
- ### Tại sao File-Based?
91
-
92
- Chúng tôi đã test memsearch, qmd, mem0, memories.sh — tất cả failed vì nhiều lý do (xem [RESEARCH.md](./docs/RESEARCH.md)):
93
-
94
- - **Context Blindness**: Auto-capture không thể link user intent với prior analysis
95
- - **Context Bloat**: Fallback sang transcripts tốn 47k+ tokens
96
- - **Platform issues**: Dependencies không work trên Windows/VM
47
+ ### Phân tách Router
97
48
 
98
- File-based solution:
99
- - Agent ghi khi họ hiểu context (quality > automation)
100
- - Plain markdown (portable, git-versionable, human-readable)
101
- - Không dependencies (works everywhere)
49
+ - **AGENTS.md**: Router cốt lõi được quản lý bởi thư viện. Không sửa file này trực tiếp vì nó có thể bị ghi đè khi update.
50
+ - **.agents/CUSTOM.md**: Nơi dành riêng cho dự án của bạn để viết custom rules, quyết định kiến trúc và mapping tài liệu.
102
51
 
103
- ## Cross-IDE Compatibility
104
-
105
- Mặc định, công cụ chỉ scaffold `AGENTS.md`, một chuẩn router file đang phổ biến.
106
-
107
- Nếu công cụ của bạn yêu cầu một file cụ thể (vd: Cursor yêu cầu `.cursorrules`, GitHub Copilot yêu cầu `.github/copilot-instructions.md`), bạn có thể đơn giản dùng symlink hoặc copy `AGENTS.md`:
108
-
109
- ```bash
110
- # Cho Cursor
111
- ln -s AGENTS.md .cursorrules
112
-
113
- # Cho GitHub Copilot
114
- mkdir -p .github && ln -s ../AGENTS.md .github/copilot-instructions.md
115
- ```
52
+ ### Các file bộ nhớ
116
53
 
117
- Tất cả các công cụ sẽ cùng đọc chung cấu trúc bộ nhớ bên trong thư mục `.agents/`.
54
+ | File | Mục đích |
55
+ |------|----------|
56
+ | .agents/MEMORY.md | Các quyết định quan trọng (mỗi dòng 1 quyết định) |
57
+ | .agents/TASKS.md | Công việc hiện tại và các bước tiếp theo |
58
+ | .agents/spec/*.md | Tài liệu kỹ thuật chi tiết |
118
59
 
119
- ## Tài liệu
60
+ ## Tại sao dùng File-Based?
120
61
 
121
- - **[RESEARCH.md](./docs/RESEARCH.md)** Vấn đề, thử nghiệm, so sánh, tại sao file-based thắng
122
- - **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** 4-layer design, scalability, migration
62
+ - **Chính xác**: AI chỉ ghi dữ liệu khi đã hiểu bối cảnh (chất lượng > tự động hóa).
63
+ - **Linh hoạt**: Markdown đơn thuần, dễ di chuyển, có thể quản lý bằng Git và con người có thể đọc được.
64
+ - **Tối giản**: Không phụ thuộc bên ngoài, không chạy ngầm, không cần API keys.
123
65
 
124
66
  ## License
125
67
 
package/dist/bin/cli.js CHANGED
@@ -1,19 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/core/scaffold.ts
3
+ // bin/cli.ts
4
+ import { existsSync as existsSync3 } from "fs";
5
+ import { join as join3 } from "path";
6
+
7
+ // src/scaffold.ts
4
8
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
5
9
  import { join, resolve, dirname } from "path";
6
10
  import { fileURLToPath } from "url";
7
11
 
8
- // src/core/types.ts
12
+ // src/types.ts
9
13
  var AGENTS_DIR = ".agents";
10
14
  var SPEC_DIR = ".agents/spec";
11
15
  var MEMORY_FILE = ".agents/MEMORY.md";
12
16
  var MEMORY_DETAIL_FILE = ".agents/MEMORY-DETAIL.md";
13
17
  var TASKS_FILE = ".agents/TASKS.md";
18
+ var CUSTOM_FILE = ".agents/CUSTOM.md";
14
19
  var AGENTS_MD = "AGENTS.md";
15
20
 
16
- // src/core/scaffold.ts
21
+ // src/scaffold.ts
17
22
  function getTemplatesDir() {
18
23
  const thisDir = dirname(fileURLToPath(import.meta.url));
19
24
  const fromSource = resolve(thisDir, "../../templates");
@@ -54,7 +59,8 @@ function scaffold(projectDir, options = {}) {
54
59
  const coreFiles = [
55
60
  { target: MEMORY_FILE, template: "MEMORY.md" },
56
61
  { target: MEMORY_DETAIL_FILE, template: "MEMORY-DETAIL.md" },
57
- { target: TASKS_FILE, template: "TASKS.md" }
62
+ { target: TASKS_FILE, template: "TASKS.md" },
63
+ { target: CUSTOM_FILE, template: "CUSTOM.md" }
58
64
  ];
59
65
  for (const { target, template } of coreFiles) {
60
66
  const targetPath = join(projectDir, target);
@@ -99,14 +105,24 @@ function guessProjectName(dir) {
99
105
  }
100
106
  return dir.split("/").pop() || "Project";
101
107
  }
108
+ function updateRouter(projectDir) {
109
+ const targetPath = join(projectDir, AGENTS_MD);
110
+ if (!existsSync(targetPath)) return false;
111
+ const projectName = guessProjectName(projectDir);
112
+ const vars = { PROJECT_NAME: projectName };
113
+ const content = applyVars(readTemplate("AGENTS.md"), vars);
114
+ writeFileSync(targetPath, content);
115
+ return true;
116
+ }
102
117
 
103
- // src/core/doctor.ts
118
+ // src/doctor.ts
104
119
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
105
120
  import { join as join2 } from "path";
106
121
  function doctor(projectDir) {
107
122
  const issues = [];
108
123
  const required = [
109
124
  { file: AGENTS_MD, desc: "Root router file" },
125
+ { file: CUSTOM_FILE, desc: "Project specific rules" },
110
126
  { file: MEMORY_FILE, desc: "Long-term memory" },
111
127
  { file: TASKS_FILE, desc: "Working memory" }
112
128
  ];
@@ -162,6 +178,7 @@ function printUsage() {
162
178
 
163
179
  Usage:
164
180
  agent-memory init [options] Scaffold .agents/ structure and AGENTS.md
181
+ agent-memory update Update AGENTS.md router to latest version
165
182
  agent-memory doctor Validate .agents/ structure
166
183
  agent-memory help Show this help
167
184
 
@@ -208,6 +225,26 @@ Initializing agent memory in ${cwd}...
208
225
  console.log(" 3. Agent will read rules and write to .agents/MEMORY.md automatically");
209
226
  console.log("");
210
227
  }
228
+ async function runUpdate() {
229
+ const cwd = process.cwd();
230
+ const agentsMdPath = join3(cwd, AGENTS_MD);
231
+ if (!existsSync3(agentsMdPath)) {
232
+ console.error("\u2717 AGENTS.md not found. Please run 'agent-memory init' first.");
233
+ process.exit(1);
234
+ }
235
+ console.log(`
236
+ Updating ${AGENTS_MD} in ${cwd}...
237
+ `);
238
+ const updated = updateRouter(cwd);
239
+ if (updated) {
240
+ console.log(` \u2713 ${AGENTS_MD} updated to the latest template.`);
241
+ console.log(` (Note: Your custom rules in .agents/CUSTOM.md were not affected)`);
242
+ } else {
243
+ console.error("\u2717 Failed to update AGENTS.md");
244
+ process.exit(1);
245
+ }
246
+ console.log("");
247
+ }
211
248
  function runDoctor() {
212
249
  const cwd = process.cwd();
213
250
  const result = doctor(cwd);
@@ -234,6 +271,12 @@ switch (command) {
234
271
  process.exit(1);
235
272
  });
236
273
  break;
274
+ case "update":
275
+ runUpdate().catch((err) => {
276
+ console.error("Error:", err.message);
277
+ process.exit(1);
278
+ });
279
+ break;
237
280
  case "doctor":
238
281
  runDoctor();
239
282
  break;
package/dist/index.js CHANGED
@@ -1,17 +1,18 @@
1
- // src/core/scaffold.ts
1
+ // src/scaffold.ts
2
2
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
3
3
  import { join, resolve, dirname } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
 
6
- // src/core/types.ts
6
+ // src/types.ts
7
7
  var AGENTS_DIR = ".agents";
8
8
  var SPEC_DIR = ".agents/spec";
9
9
  var MEMORY_FILE = ".agents/MEMORY.md";
10
10
  var MEMORY_DETAIL_FILE = ".agents/MEMORY-DETAIL.md";
11
11
  var TASKS_FILE = ".agents/TASKS.md";
12
+ var CUSTOM_FILE = ".agents/CUSTOM.md";
12
13
  var AGENTS_MD = "AGENTS.md";
13
14
 
14
- // src/core/scaffold.ts
15
+ // src/scaffold.ts
15
16
  function getTemplatesDir() {
16
17
  const thisDir = dirname(fileURLToPath(import.meta.url));
17
18
  const fromSource = resolve(thisDir, "../../templates");
@@ -52,7 +53,8 @@ function scaffold(projectDir, options = {}) {
52
53
  const coreFiles = [
53
54
  { target: MEMORY_FILE, template: "MEMORY.md" },
54
55
  { target: MEMORY_DETAIL_FILE, template: "MEMORY-DETAIL.md" },
55
- { target: TASKS_FILE, template: "TASKS.md" }
56
+ { target: TASKS_FILE, template: "TASKS.md" },
57
+ { target: CUSTOM_FILE, template: "CUSTOM.md" }
56
58
  ];
57
59
  for (const { target, template } of coreFiles) {
58
60
  const targetPath = join(projectDir, target);
@@ -97,134 +99,41 @@ function guessProjectName(dir) {
97
99
  }
98
100
  return dir.split("/").pop() || "Project";
99
101
  }
100
-
101
- // src/core/memory.ts
102
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
103
- import { join as join2 } from "path";
104
- function appendMemory(projectDir, entry) {
105
- const filePath = join2(projectDir, MEMORY_FILE);
106
- if (!existsSync2(filePath)) {
107
- throw new Error(`${MEMORY_FILE} not found. Run 'agent-memory init' first.`);
108
- }
109
- const content = readFileSync2(filePath, "utf-8");
110
- const category = entry.category || "Decisions";
111
- const line = `- ${entry.date}: ${entry.content}`;
112
- const categoryHeader = `## ${category}`;
113
- const headerIndex = content.indexOf(categoryHeader);
114
- let updated;
115
- if (headerIndex === -1) {
116
- updated = content.trimEnd() + `
117
-
118
- ${categoryHeader}
119
- ${line}
120
- `;
121
- } else {
122
- const afterHeader = headerIndex + categoryHeader.length;
123
- const nextHeaderIndex = content.indexOf("\n## ", afterHeader);
124
- const insertAt = nextHeaderIndex === -1 ? content.length : nextHeaderIndex;
125
- const categoryContent = content.slice(afterHeader, insertAt);
126
- const lastLineEnd = afterHeader + categoryContent.trimEnd().length;
127
- updated = content.slice(0, lastLineEnd) + "\n" + line + content.slice(lastLineEnd);
128
- }
129
- writeFileSync2(filePath, updated);
130
- }
131
- function readMemory(projectDir) {
132
- const filePath = join2(projectDir, MEMORY_FILE);
133
- if (!existsSync2(filePath)) return {};
134
- const content = readFileSync2(filePath, "utf-8");
135
- const categories = {};
136
- let currentCategory = "_uncategorized";
137
- for (const line of content.split("\n")) {
138
- const headerMatch = line.match(/^## (.+)/);
139
- if (headerMatch) {
140
- currentCategory = headerMatch[1];
141
- categories[currentCategory] = categories[currentCategory] || [];
142
- continue;
143
- }
144
- if (line.startsWith("- ") && currentCategory) {
145
- categories[currentCategory] = categories[currentCategory] || [];
146
- categories[currentCategory].push(line.slice(2));
147
- }
148
- }
149
- return categories;
150
- }
151
-
152
- // src/core/tasks.ts
153
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
154
- import { join as join3 } from "path";
155
- function readTasks(projectDir) {
156
- const filePath = join3(projectDir, TASKS_FILE);
157
- const result = {
158
- in_progress: [],
159
- up_next: [],
160
- completed: []
161
- };
162
- if (!existsSync3(filePath)) return result;
163
- const content = readFileSync3(filePath, "utf-8");
164
- let currentSection = null;
165
- for (const line of content.split("\n")) {
166
- if (line.startsWith("## In Progress")) {
167
- currentSection = "in_progress";
168
- continue;
169
- }
170
- if (line.startsWith("## Up Next")) {
171
- currentSection = "up_next";
172
- continue;
173
- }
174
- if (line.startsWith("## Completed")) {
175
- currentSection = "completed";
176
- continue;
177
- }
178
- if (currentSection && line.startsWith("- ")) {
179
- result[currentSection].push(line.slice(2));
180
- }
181
- }
182
- return result;
183
- }
184
- function writeTasks(projectDir, tasks) {
185
- const filePath = join3(projectDir, TASKS_FILE);
186
- const content = `# Current Tasks
187
-
188
- Working memory for cross-session continuity. Update before ending a session.
189
-
190
- ---
191
-
192
- ## In Progress
193
- ${tasks.in_progress.map((t) => `- ${t}`).join("\n") || ""}
194
-
195
- ## Up Next
196
- ${tasks.up_next.map((t) => `- ${t}`).join("\n") || ""}
197
-
198
- ## Completed
199
- ${tasks.completed.map((t) => `- ${t}`).join("\n") || ""}
200
- `;
201
- writeFileSync3(filePath, content);
102
+ function updateRouter(projectDir) {
103
+ const targetPath = join(projectDir, AGENTS_MD);
104
+ if (!existsSync(targetPath)) return false;
105
+ const projectName = guessProjectName(projectDir);
106
+ const vars = { PROJECT_NAME: projectName };
107
+ const content = applyVars(readTemplate("AGENTS.md"), vars);
108
+ writeFileSync(targetPath, content);
109
+ return true;
202
110
  }
203
111
 
204
- // src/core/doctor.ts
205
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
206
- import { join as join4 } from "path";
112
+ // src/doctor.ts
113
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
114
+ import { join as join2 } from "path";
207
115
  function doctor(projectDir) {
208
116
  const issues = [];
209
117
  const required = [
210
118
  { file: AGENTS_MD, desc: "Root router file" },
119
+ { file: CUSTOM_FILE, desc: "Project specific rules" },
211
120
  { file: MEMORY_FILE, desc: "Long-term memory" },
212
121
  { file: TASKS_FILE, desc: "Working memory" }
213
122
  ];
214
123
  for (const { file, desc } of required) {
215
- const filePath = join4(projectDir, file);
216
- if (!existsSync4(filePath)) {
124
+ const filePath = join2(projectDir, file);
125
+ if (!existsSync2(filePath)) {
217
126
  issues.push({ level: "error", file, message: `Missing ${desc}` });
218
127
  }
219
128
  }
220
129
  for (const dir of [AGENTS_DIR, SPEC_DIR]) {
221
- if (!existsSync4(join4(projectDir, dir))) {
130
+ if (!existsSync2(join2(projectDir, dir))) {
222
131
  issues.push({ level: "error", file: dir, message: "Directory missing" });
223
132
  }
224
133
  }
225
- const agentsPath = join4(projectDir, AGENTS_MD);
226
- if (existsSync4(agentsPath)) {
227
- const content = readFileSync4(agentsPath, "utf-8");
134
+ const agentsPath = join2(projectDir, AGENTS_MD);
135
+ if (existsSync2(agentsPath)) {
136
+ const content = readFileSync2(agentsPath, "utf-8");
228
137
  if (!content.includes(".agents/")) {
229
138
  issues.push({
230
139
  level: "warning",
@@ -240,9 +149,9 @@ function doctor(projectDir) {
240
149
  });
241
150
  }
242
151
  }
243
- const memoryPath = join4(projectDir, MEMORY_FILE);
244
- if (existsSync4(memoryPath)) {
245
- const lines = readFileSync4(memoryPath, "utf-8").split("\n").length;
152
+ const memoryPath = join2(projectDir, MEMORY_FILE);
153
+ if (existsSync2(memoryPath)) {
154
+ const lines = readFileSync2(memoryPath, "utf-8").split("\n").length;
246
155
  if (lines > 150) {
247
156
  issues.push({
248
157
  level: "warning",
@@ -256,14 +165,12 @@ function doctor(projectDir) {
256
165
  export {
257
166
  AGENTS_DIR,
258
167
  AGENTS_MD,
168
+ CUSTOM_FILE,
259
169
  MEMORY_DETAIL_FILE,
260
170
  MEMORY_FILE,
261
171
  SPEC_DIR,
262
172
  TASKS_FILE,
263
- appendMemory,
264
173
  doctor,
265
- readMemory,
266
- readTasks,
267
174
  scaffold,
268
- writeTasks
175
+ updateRouter
269
176
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vuau/agent-memory",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "Structured AI memory for codebases — scaffolding CLI for OpenCode, Copilot, Cursor, Windsurf",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,6 +21,7 @@
21
21
  "prepublishOnly": "npm run build"
22
22
  },
23
23
  "devDependencies": {
24
+ "@types/node": "^25.6.0",
24
25
  "tsup": "^8.0.0",
25
26
  "typescript": "^6.0.3"
26
27
  },
@@ -41,4 +42,4 @@
41
42
  "type": "git",
42
43
  "url": "git+https://github.com/vuau/agent-memory.git"
43
44
  }
44
- }
45
+ }
@@ -1,22 +1,18 @@
1
1
  # {{PROJECT_NAME}} - AGENTS
2
2
 
3
- Router file for AI agents. Keep under 150 lines.
3
+ Router file for AI agents.
4
+
5
+ > **Note**: This file is automatically managed by `@vuau/agent-memory`.
6
+ > Do not add project-specific rules here, as they may be overwritten by `agent-memory update`.
7
+ >
8
+ > 👉 **For project-specific rules, context, and document mapping, see `.agents/CUSTOM.md`**
4
9
 
5
10
  ## Priority
6
11
  1. User request first.
7
- 2. This `AGENTS.md`.
8
- 3. Spec files in `.agents/spec/`.
9
- 4. If conflict remains, choose smallest safe change and state assumption.
10
-
11
- ## Documentation Map
12
-
13
- | Task | Spec File |
14
- |------|-----------|
15
- | Past decisions (1-line) | `.agents/MEMORY.md` |
16
- | Past decisions (full context) | `.agents/MEMORY-DETAIL.md` |
17
- | Current work in progress | `.agents/TASKS.md` |
18
-
19
- > Add your own spec files to `.agents/spec/` and reference them here.
12
+ 2. The rules in `.agents/CUSTOM.md`.
13
+ 3. This `AGENTS.md`.
14
+ 4. Spec files in `.agents/spec/`.
15
+ 5. If conflict remains, choose smallest safe change and state assumption.
20
16
 
21
17
  ## Memory Protocol
22
18
 
@@ -40,6 +36,7 @@ Before ending a session with unfinished work, move items to `## In Progress` or
40
36
  - Do not create additional memory files outside `.agents/`.
41
37
 
42
38
  ## Response Style
43
- - Concise, concrete, implementation-focused.
39
+ - Concrete, implementation-focused, caveman style (minimum words, zero fluff).
40
+ - Propose the simplest solution first (KISS & YAGNI) before writing code.
44
41
  - If uncertain, say `I don't know`, then give fastest verification step.
45
42
  - Do not invent files, APIs, or command outputs.
@@ -0,0 +1,13 @@
1
+ # Project Rules & Document Map
2
+
3
+ ## Documentation Map
4
+
5
+ | Area / Feature | Spec File |
6
+ |----------------|-----------|
7
+ | Example: Database Schema | `.agents/spec/database.md` |
8
+
9
+ > Add your own spec files to `.agents/spec/` and reference them here.
10
+
11
+ ## Custom Rules
12
+
13
+ - Add your project-specific rules here.
@@ -1,8 +1,5 @@
1
1
  # Memory Detail
2
2
 
3
- Full Problem/Solution context for entries in MEMORY.md. Read on-demand when needing to understand *why* a decision was made.
4
-
5
- ---
6
3
 
7
4
  ## Example Category
8
5
 
@@ -1,8 +1,5 @@
1
1
  # Project Memory
2
2
 
3
- Curated decisions, patterns, and pointers. Agents: read before implementing.
4
-
5
- ---
6
3
 
7
4
  ## Architecture
8
5
  <!-- Add pointers to spec files: → Full spec: `.agents/spec/architecture.md` -->
@@ -1,8 +1,5 @@
1
- # Current Tasks
1
+ # Tasks
2
2
 
3
- Working memory for cross-session continuity. Update before ending a session.
4
-
5
- ---
6
3
 
7
4
  ## In Progress
8
5