@xqli02/mneme 0.1.0

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 ADDED
@@ -0,0 +1,175 @@
1
+ # mneme
2
+
3
+ 面向长期工程项目的 AI Agent 上下文与记忆架构。解决 coding agent 在跨 session 工作中的状态丢失、事实遗忘和重复分析问题。
4
+
5
+ > 架构设计详见 [ARCHITECTURE.md](ARCHITECTURE.md)
6
+
7
+ ---
8
+
9
+ ## 快速开始
10
+
11
+ ```bash
12
+ # 安装
13
+ npm install -g @xqli02/mneme
14
+
15
+ # 在任意项目目录下初始化
16
+ mkdir my-project && cd my-project
17
+ mneme init
18
+
19
+ # 开始使用
20
+ mneme
21
+ ```
22
+
23
+ `mneme init` 会自动完成:
24
+ 1. 安装依赖(git、dolt、bd)
25
+ 2. 初始化 git 仓库
26
+ 3. 创建三层架构文件(`.openclaw/`、`.opencode/`、`AGENTS.md`、`.gitignore`)
27
+ 4. 启动 dolt server + 初始化 beads
28
+
29
+ ### CLI 命令
30
+
31
+ ```bash
32
+ mneme # 启动 opencode TUI(等同于 mneme start)
33
+ mneme init # 初始化当前目录
34
+ mneme doctor # 检查依赖和项目健康状态
35
+ mneme status # 三层记忆状态总览
36
+ mneme compact # 压缩前持久化检查
37
+ mneme version # 打印版本号
38
+
39
+ # OpenClaw — 长期事实管理
40
+ mneme facts # 查看事实文件列表
41
+ mneme facts --stats # 查看行数/预算统计
42
+ mneme facts architecture # 查看某个事实文件内容
43
+ mneme propose --file=pitfalls --content="..." --reason="..." # 提议新事实
44
+ mneme review # 列出待审批提议
45
+ mneme review <id> --approve # 批准提议,写入 facts
46
+ mneme review <id> --reject # 拒绝提议
47
+
48
+ # Beads — 任务管理
49
+ mneme ready # 查看可执行任务
50
+ mneme list --status=open # 列出所有未完成任务
51
+ mneme show <id> # 查看任务详情
52
+ mneme create --title="..." --description="..." --type=task -p 2 # 创建任务
53
+ mneme update <id> --notes="进度说明" # 更新任务
54
+ mneme close <id> --reason="完成" # 关闭任务
55
+
56
+ # OpenCode — AI agent(opencode 透传)
57
+ mneme auto # 自主 agent 监督循环(自动选取任务)
58
+ mneme auto "fix the bug" # 指定目标启动
59
+ mneme auto --attach URL # 连接已有 opencode 服务
60
+ mneme run "fix the bug" # 非交互模式运行
61
+ mneme web # 启动 Web 界面
62
+ mneme serve # 启动 headless server
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 自主模式 (`mneme auto`)
68
+
69
+ `mneme auto` 启动一个自主 agent 监督循环,自动从 beads 中选取任务并驱动 opencode 完成:
70
+
71
+ ```bash
72
+ mneme auto # 自动从 ready beads 中选取任务
73
+ mneme auto "Build auth module" # 以指定目标启动
74
+ mneme auto --attach http://localhost:4097 # 连接已有 opencode 服务
75
+ mneme auto --port 4097 # 指定服务端口
76
+ mneme auto --max-turns 50 # 限制最大轮次
77
+ ```
78
+
79
+ 运行时可随时输入:
80
+ - **任意文本** — 在下一轮注入反馈给 agent
81
+ - `/status` — 查看当前任务状态
82
+ - `/skip` — 跳过当前 bead
83
+ - `/quit` — 停止并退出
84
+
85
+ 工作流程:
86
+ 1. 启动(或连接)opencode serve 后端
87
+ 2. 注入系统上下文(AGENTS.md + OpenClaw facts)
88
+ 3. 从 `mneme ready` 选取最高优先级 bead
89
+ 4. Claim bead → 构造 prompt → 发送给 opencode
90
+ 5. 流式展示 agent 进度
91
+ 6. 完成后自动选取下一个 bead
92
+ 7. 无可执行 bead 时等待用户输入
93
+
94
+ ---
95
+
96
+ ## 三层记忆架构
97
+
98
+ | 层 | 工具 | 职责 | 生命周期 |
99
+ |---|---|---|---|
100
+ | OpenClaw | `.openclaw/facts/*.md` | 不能忘的事实 | 跨项目 |
101
+ | Beads | [bd](https://github.com/steveyegge/beads) | 不能断的进度 | 跨 session |
102
+ | OpenCode | 对话上下文 | 当下的执行 | 单 session |
103
+
104
+ ## 项目结构
105
+
106
+ `mneme init` 创建的文件:
107
+
108
+ ```
109
+ .openclaw/facts/ 长期事实(架构、约束、红线、陷阱)
110
+ .openclaw/proposals/ 待审批的事实提议(mneme propose 创建)
111
+ .beads/ 任务状态(由 bd 管理)
112
+ .opencode/prompt.md Session 启动 prompt
113
+ AGENTS.md Agent 行为规则
114
+ .gitignore 排除 dolt 数据等运行时文件
115
+ ```
116
+
117
+ ## Session 工作流
118
+
119
+ ```bash
120
+ # 1. 读取长期事实(agent 自动执行)
121
+ mneme facts
122
+
123
+ # 2. 查看可执行任务
124
+ mneme ready
125
+
126
+ # 3. Claim 一个任务
127
+ mneme update <id> --status=in_progress
128
+
129
+ # 4. 工作、记录进度
130
+ mneme update <id> --notes="完成了 X,发现了 Y"
131
+
132
+ # 5. 完成
133
+ mneme close <id> --reason="Done"
134
+ ```
135
+
136
+ ## 什么信息放哪一层?
137
+
138
+ ```
139
+ 新信息产生
140
+
141
+ ├─ 6 个月后还有用?
142
+ │ ├─ YES + 事实/约束/教训 → OpenClaw(提议写入,需人工确认)
143
+ │ ├─ YES + 待办/进度 → Beads(直接写入)
144
+ │ └─ NO → 下个 session 需要?
145
+ │ ├─ YES → Beads
146
+ │ └─ NO → 留在 OpenCode,不持久化
147
+ ```
148
+
149
+ | 信息示例 | 写入层 |
150
+ |---|---|
151
+ | "数据库必须用 PostgreSQL" | OpenClaw `mneme propose --file=architecture` |
152
+ | "禁止在生产环境直接改数据" | OpenClaw `mneme propose --file=invariants` |
153
+ | "需要实现用户认证模块" | Beads `mneme create` |
154
+ | "函数第 3 个参数是 timeout" | 不写,留在 OpenCode |
155
+
156
+ ## 核心文件说明
157
+
158
+ ### `.openclaw/facts/`
159
+
160
+ 存放已确认的长期工程事实,agent 不可单方面修改。
161
+
162
+ | 文件 | 内容 |
163
+ |---|---|
164
+ | `architecture.md` | 架构决策 |
165
+ | `invariants.md` | 不可违反的约束与红线 |
166
+ | `performance_rules.md` | 性能规则 |
167
+ | `pitfalls.md` | 已知陷阱与教训 |
168
+
169
+ ### `AGENTS.md`
170
+
171
+ 定义 agent 的 session 启动流程、执行规则、三层路由决策树、compaction 前动作和禁止行为。
172
+
173
+ ### `.opencode/prompt.md`
174
+
175
+ 每个新 session 的启动 prompt,引导 agent 按正确顺序建立上下文。
package/bin/mneme.mjs ADDED
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * mneme CLI — Three-layer memory architecture for AI coding agents.
5
+ *
6
+ * Unified entry point that routes to:
7
+ * 1. mneme's own commands (init, doctor, status, compact, facts, propose, review, auto)
8
+ * 2. opencode commands (run, web, serve, etc.) — default fallback
9
+ * 3. bd/beads commands (ready, list, create, close, etc.)
10
+ *
11
+ * Usage:
12
+ * mneme Start opencode (same as `mneme start`)
13
+ * mneme init Initialize mneme in the current directory
14
+ * mneme doctor Check dependencies and project health
15
+ * mneme status Show three-layer memory dashboard
16
+ * mneme compact Pre-compaction persistence check
17
+ * mneme facts View OpenClaw facts
18
+ * mneme ready Show ready tasks (bd ready)
19
+ * mneme list List tasks (bd list)
20
+ * mneme create Create task (bd create)
21
+ * mneme close Close task (bd close)
22
+ * mneme run [msg..] Run opencode with a message (non-interactive)
23
+ * mneme <opencode-subcommand> [args..] Pass through to opencode
24
+ */
25
+
26
+ import { readFileSync, existsSync } from "node:fs";
27
+ import { fileURLToPath } from "node:url";
28
+ import { dirname, join } from "node:path";
29
+ import { spawnSync } from "node:child_process";
30
+ import { createInterface } from "node:readline";
31
+
32
+ const __filename = fileURLToPath(import.meta.url);
33
+ const __dirname = dirname(__filename);
34
+ const pkg = JSON.parse(
35
+ readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
36
+ );
37
+
38
+ const args = process.argv.slice(2);
39
+ const [command] = args;
40
+
41
+ // Simple bold helper for help text
42
+ const bold = (s) =>
43
+ process.stdout.isTTY && process.env.FORCE_COLOR !== "0"
44
+ ? `\x1b[1m${s}\x1b[0m`
45
+ : s;
46
+
47
+ // ── Command routing ─────────────────────────────────────────────────────────
48
+
49
+ // mneme's own commands
50
+ const MNEME_COMMANDS = new Set([
51
+ "init",
52
+ "doctor",
53
+ "status",
54
+ "compact",
55
+ "facts",
56
+ "propose",
57
+ "review",
58
+ "auto",
59
+ "version",
60
+ "--version",
61
+ "-v",
62
+ "help",
63
+ "--help",
64
+ "-h",
65
+ ]);
66
+
67
+ // bd (beads) subcommands promoted to mneme top-level — the essential set
68
+ // for agent workflow. All other commands default to opencode.
69
+ const BD_COMMANDS = new Set([
70
+ "ready",
71
+ "list",
72
+ "show",
73
+ "create",
74
+ "update",
75
+ "close",
76
+ "blocked",
77
+ "dep",
78
+ ]);
79
+
80
+ switch (command) {
81
+ case "init": {
82
+ const { init } = await import("../src/commands/init.mjs");
83
+ await init();
84
+ break;
85
+ }
86
+ case "doctor": {
87
+ const { doctor } = await import("../src/commands/doctor.mjs");
88
+ await doctor();
89
+ break;
90
+ }
91
+ case "status": {
92
+ const { status } = await import("../src/commands/status.mjs");
93
+ await status();
94
+ break;
95
+ }
96
+ case "compact": {
97
+ const { compact } = await import("../src/commands/compact.mjs");
98
+ await compact();
99
+ break;
100
+ }
101
+ case "facts": {
102
+ const { facts } = await import("../src/commands/facts.mjs");
103
+ await facts(args.slice(1));
104
+ break;
105
+ }
106
+ case "propose": {
107
+ const { propose } = await import("../src/commands/propose.mjs");
108
+ await propose(args.slice(1));
109
+ break;
110
+ }
111
+ case "review": {
112
+ const { review } = await import("../src/commands/review.mjs");
113
+ await review(args.slice(1));
114
+ break;
115
+ }
116
+ case "auto": {
117
+ const { auto } = await import("../src/commands/auto.mjs");
118
+ await auto(args.slice(1));
119
+ break;
120
+ }
121
+ case "version":
122
+ case "--version":
123
+ case "-v":
124
+ console.log(`mneme ${pkg.version}`);
125
+ break;
126
+ case "help":
127
+ case "--help":
128
+ case "-h":
129
+ console.log(`
130
+ mneme ${pkg.version} — Three-layer memory architecture for AI coding agents
131
+
132
+ Usage:
133
+ mneme Start opencode TUI
134
+
135
+ ${bold("Memory management (OpenClaw):")}
136
+ mneme facts [name] [--stats] View facts
137
+ mneme propose --file=... --content=... --reason=...
138
+ Propose a new fact (pending human review)
139
+ mneme review List pending proposals
140
+ mneme review <id> --approve Approve and write to facts
141
+ mneme review <id> --reject Reject proposal
142
+
143
+ ${bold("Project health:")}
144
+ mneme init Initialize mneme in the current directory
145
+ mneme doctor Check dependencies and project health
146
+ mneme status Show three-layer memory dashboard
147
+ mneme compact Pre-compaction persistence check
148
+
149
+ ${bold("Task management (beads):")}
150
+ mneme ready Show tasks with no blockers
151
+ mneme list [--status=STATUS] List tasks
152
+ mneme show <id> Show task details
153
+ mneme create --title="..." Create a new task
154
+ mneme update <id> [--notes..] Update a task
155
+ mneme close <id> [--reason..] Close a task
156
+ mneme blocked Show blocked tasks
157
+ mneme dep add <child> <parent> Add dependency
158
+
159
+ ${bold("AI agent (opencode):")}
160
+ mneme auto Autonomous agent supervisor loop
161
+ mneme auto "Build auth" Start with a specific goal
162
+ mneme auto --attach URL Attach to existing server
163
+ mneme start Start opencode TUI (same as bare mneme)
164
+ mneme run [message..] Run opencode non-interactively
165
+ mneme web Start web interface
166
+ mneme serve Start headless server
167
+
168
+ mneme version Print version
169
+
170
+ Quickstart:
171
+ mkdir my-project && cd my-project
172
+ mneme init
173
+ mneme
174
+ `);
175
+ break;
176
+ default:
177
+ // Route: bd commands → bd, everything else → opencode (default)
178
+ if (!command) {
179
+ // bare `mneme` → check init, then launch opencode TUI
180
+ await ensureInitialized();
181
+ launchOpencode([]);
182
+ } else if (BD_COMMANDS.has(command)) {
183
+ launchBd(args);
184
+ } else {
185
+ launchOpencode(args);
186
+ }
187
+ break;
188
+ }
189
+
190
+ /**
191
+ * Check if mneme is initialized in the current directory.
192
+ * If not, prompt user to run init.
193
+ */
194
+ async function ensureInitialized() {
195
+ if (existsSync(".openclaw/facts") && existsSync("AGENTS.md")) {
196
+ return; // already initialized
197
+ }
198
+
199
+ const answer = await ask(
200
+ "mneme is not initialized in this directory. Run mneme init? [Y/n] ",
201
+ );
202
+
203
+ if (answer === "" || answer.toLowerCase().startsWith("y")) {
204
+ const { init } = await import("../src/commands/init.mjs");
205
+ await init();
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Prompt user for a single line of input.
211
+ */
212
+ function ask(question) {
213
+ return new Promise((resolve) => {
214
+ const rl = createInterface({
215
+ input: process.stdin,
216
+ output: process.stdout,
217
+ });
218
+ rl.question(question, (answer) => {
219
+ rl.close();
220
+ resolve(answer.trim());
221
+ });
222
+ });
223
+ }
224
+
225
+ /**
226
+ * Launch opencode, forwarding arguments.
227
+ * `mneme start` is an alias for bare `opencode` (no args).
228
+ */
229
+ function launchOpencode(args) {
230
+ // Resolve "start" alias: `mneme start` → `opencode` (no subcommand)
231
+ let ocArgs = [...args];
232
+ if (ocArgs[0] === "start") {
233
+ ocArgs = ocArgs.slice(1);
234
+ }
235
+
236
+ launchExternal("opencode", ocArgs, {
237
+ notFoundMsg:
238
+ "Error: opencode is not installed or not in PATH.\n" +
239
+ "Install it: https://opencode.ai\n" +
240
+ 'Or run "mneme doctor" to check dependencies.',
241
+ });
242
+ }
243
+
244
+ /**
245
+ * Launch bd (beads), forwarding arguments.
246
+ * `mneme bd ready` → `bd ready`
247
+ */
248
+ function launchBd(args) {
249
+ launchExternal("bd", args, {
250
+ notFoundMsg:
251
+ "Error: bd (beads) is not installed or not in PATH.\n" +
252
+ "Run `mneme init` to install it, or see https://github.com/steveyegge/beads",
253
+ });
254
+ }
255
+
256
+ /**
257
+ * Launch an external binary, forwarding arguments and inheriting stdio.
258
+ */
259
+ function launchExternal(bin, args, { notFoundMsg }) {
260
+ const result = spawnSync(bin, args, {
261
+ stdio: "inherit",
262
+ env: { ...process.env },
263
+ });
264
+
265
+ if (result.error) {
266
+ if (result.error.code === "ENOENT") {
267
+ console.error(notFoundMsg);
268
+ process.exit(1);
269
+ }
270
+ console.error(`Error launching ${bin}: ${result.error.message}`);
271
+ process.exit(1);
272
+ }
273
+
274
+ process.exit(result.status ?? 0);
275
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@xqli02/mneme",
3
+ "version": "0.1.0",
4
+ "description": "Three-layer memory architecture for AI coding agents (OpenClaw + Beads + OpenCode)",
5
+ "type": "module",
6
+ "bin": {
7
+ "mneme": "bin/mneme.mjs"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "src/"
12
+ ],
13
+ "keywords": [
14
+ "ai",
15
+ "agent",
16
+ "memory",
17
+ "coding-agent",
18
+ "opencode",
19
+ "beads",
20
+ "context-management"
21
+ ],
22
+ "author": "CVPaul",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/CVPaul/mneme.git"
27
+ },
28
+ "engines": {
29
+ "node": ">=18"
30
+ }
31
+ }