@s_s/mnemo 1.3.0 → 1.4.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 +32 -6
- package/build/core/config.d.ts +5 -0
- package/build/core/config.js +10 -0
- package/build/core/config.js.map +1 -1
- package/build/hooks/installer.d.ts +20 -0
- package/build/hooks/installer.js +124 -0
- package/build/hooks/installer.js.map +1 -0
- package/build/hooks/reminders.d.ts +47 -0
- package/build/hooks/reminders.js +191 -0
- package/build/hooks/reminders.js.map +1 -0
- package/build/prompts/templates.js +74 -17
- package/build/prompts/templates.js.map +1 -1
- package/build/tools/setup.js +70 -32
- package/build/tools/setup.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
[中文文档](./docs/README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> _Mnemosyne, mother of all creation, stood against Lethe. Mnemo keeps only what still matters._
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Persistent, high-value long-term context for AI coding assistants via [MCP](https://modelcontextprotocol.io/).
|
|
8
|
+
|
|
9
|
+
Mnemo is not a transcript archive. It captures only the context that will still matter across future sessions — decisions, preferences, rules, and unresolved threads — and makes it available through semantic search. Think of it as durable long-term memory for your AI agent.
|
|
8
10
|
|
|
9
11
|
## Features
|
|
10
12
|
|
|
13
|
+
- **Memory types** — 8 semantic categories (preference, profile, goal, continuity, fact, decision, rule, experience) with save-time classification
|
|
14
|
+
- **Lifecycle hooks** — per-turn reminders injected via agent-native hooks (Claude Code, Codex, OpenClaw, OpenCode) so the agent actually remembers to use memory tools
|
|
11
15
|
- **Hybrid search** — find memories by meaning and keywords (vector + keyword, with automatic fallback)
|
|
12
16
|
- **Progressive disclosure** — search returns summaries; retrieve full content on demand
|
|
13
|
-
- **Multi-agent support** — works with OpenCode, Claude Code,
|
|
17
|
+
- **Multi-agent support** — works with OpenCode, Claude Code, OpenClaw, and Codex; auto-detects agent type via MCP protocol
|
|
14
18
|
- **Fully local** — no API calls, no cloud storage; all data stays on your machine
|
|
15
19
|
- **Auto-prompted** — injects instructions into your agent's config so it knows when to save and recall memories
|
|
16
20
|
- **Compression workflow** — atomic distillation of old notes into fewer, concise ones
|
|
@@ -101,13 +105,18 @@ mcporter config add mnemo --command mnemo --scope home
|
|
|
101
105
|
|
|
102
106
|
### Initialize
|
|
103
107
|
|
|
104
|
-
Once connected, call the `memory_setup` tool to
|
|
108
|
+
Once connected, call the `memory_setup` tool to initialize Mnemo:
|
|
105
109
|
|
|
106
110
|
```
|
|
107
111
|
> Use the memory_setup tool to initialize Mnemo
|
|
108
112
|
```
|
|
109
113
|
|
|
110
|
-
This
|
|
114
|
+
This does two things:
|
|
115
|
+
|
|
116
|
+
1. **Prompt injection** — writes memory management instructions into your agent's config file (e.g., `AGENTS.md` for OpenCode, `CLAUDE.md` for Claude Code)
|
|
117
|
+
2. **Hook installation** — installs lifecycle hooks that remind the agent to use memory tools at key moments (per-turn for Claude Code/Codex, session-start for OpenClaw, session lifecycle events for OpenCode)
|
|
118
|
+
|
|
119
|
+
Both steps are independent — if one fails, the other still succeeds. Agent type is auto-detected via MCP protocol, with file-based detection as fallback.
|
|
111
120
|
|
|
112
121
|
By default, `memory_setup()` initializes **global** memory shared across projects. If you want project-isolated memory, call `memory_setup` with `scope: "project"`.
|
|
113
122
|
|
|
@@ -187,13 +196,30 @@ Mnemo provides 7 MCP tools:
|
|
|
187
196
|
| Tool | Description |
|
|
188
197
|
| ----------------------- | ------------------------------------------------------------------- |
|
|
189
198
|
| `memory_setup` | Initialize Mnemo — inject usage instructions and set up storage |
|
|
190
|
-
| `memory_save` | Save a memory note with optional tags and source
|
|
199
|
+
| `memory_save` | Save a memory note with type, optional tags, and source |
|
|
191
200
|
| `memory_search` | Hybrid search across memories; returns summaries (supports filters) |
|
|
192
201
|
| `memory_get` | Retrieve full content of specific notes by ID |
|
|
193
202
|
| `memory_compress` | List all notes for review/distillation |
|
|
194
203
|
| `memory_compress_apply` | Atomically save distilled notes and delete originals |
|
|
195
204
|
| `memory_delete` | Delete notes by ID |
|
|
196
205
|
|
|
206
|
+
## Memory Model
|
|
207
|
+
|
|
208
|
+
Every memory note is classified into one of 8 types before saving:
|
|
209
|
+
|
|
210
|
+
| Type | Purpose | Example |
|
|
211
|
+
| ------------ | ----------------------------------------------- | ----------------------------------------------- |
|
|
212
|
+
| `preference` | User preferences and collaboration habits | "Prefers 4-space indentation, single quotes" |
|
|
213
|
+
| `profile` | Stable background about user, project, or topic | "Project uses Next.js 14 with App Router" |
|
|
214
|
+
| `goal` | Long-term directions and objectives | "Migrate from REST to GraphQL by Q3" |
|
|
215
|
+
| `continuity` | Unresolved threads to resume later | "Auth module: left off at refresh token logic" |
|
|
216
|
+
| `fact` | Stable objective information | "Production DB is on PostgreSQL 16" |
|
|
217
|
+
| `decision` | Confirmed choices from a discussion | "Chose Prisma over Drizzle for type safety" |
|
|
218
|
+
| `rule` | Reusable conventions and agreements | "All API errors return { code, message } shape" |
|
|
219
|
+
| `experience` | Validated, reusable lessons (high bar) | "Batch DB writes cut migration time by 10x" |
|
|
220
|
+
|
|
221
|
+
A memory must meet at least 2 of 3 criteria to be worth saving: (1) useful across future sessions, (2) affects future work, (3) would require re-alignment if forgotten.
|
|
222
|
+
|
|
197
223
|
## How It Works
|
|
198
224
|
|
|
199
225
|
### Storage
|
package/build/core/config.d.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare const AGENT_TYPES: readonly ["opencode", "claude-code", "openclaw", "codex"];
|
|
5
5
|
export type AgentType = (typeof AGENT_TYPES)[number];
|
|
6
|
+
/**
|
|
7
|
+
* Map from MCP clientInfo.name to AgentType.
|
|
8
|
+
* Used for protocol-level agent identification during the initialize handshake.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CLIENT_NAME_MAP: Record<string, AgentType>;
|
|
6
11
|
export type StorageScope = 'global' | 'project';
|
|
7
12
|
/**
|
|
8
13
|
* Memory type categories for the minimal constraint mechanism.
|
package/build/core/config.js
CHANGED
|
@@ -5,6 +5,16 @@ import fs from 'node:fs/promises';
|
|
|
5
5
|
* Supported agent tool types
|
|
6
6
|
*/
|
|
7
7
|
export const AGENT_TYPES = ['opencode', 'claude-code', 'openclaw', 'codex'];
|
|
8
|
+
/**
|
|
9
|
+
* Map from MCP clientInfo.name to AgentType.
|
|
10
|
+
* Used for protocol-level agent identification during the initialize handshake.
|
|
11
|
+
*/
|
|
12
|
+
export const CLIENT_NAME_MAP = {
|
|
13
|
+
opencode: 'opencode',
|
|
14
|
+
'claude-code': 'claude-code',
|
|
15
|
+
'openclaw-acp-client': 'openclaw',
|
|
16
|
+
'codex-mcp-client': 'codex',
|
|
17
|
+
};
|
|
8
18
|
/**
|
|
9
19
|
* Memory type categories for the minimal constraint mechanism.
|
|
10
20
|
* Each memory should be classified into one of these types before saving.
|
package/build/core/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type AgentType } from '../core/config.js';
|
|
2
|
+
export interface HookInstallResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
hookDir: string;
|
|
5
|
+
filesWritten: string[];
|
|
6
|
+
settingsUpdated: boolean;
|
|
7
|
+
/** Non-fatal messages (e.g. manual steps needed) */
|
|
8
|
+
notes: string[];
|
|
9
|
+
/** Error message if success is false */
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Install hook scripts/plugins for the given agent type.
|
|
14
|
+
* This is independent from prompt injection — either can succeed/fail without affecting the other.
|
|
15
|
+
*/
|
|
16
|
+
export declare function installHooks(agentType: AgentType): Promise<HookInstallResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Check if hooks are already installed for the given agent type.
|
|
19
|
+
*/
|
|
20
|
+
export declare function hasHooksInstalled(agentType: AgentType): Promise<boolean>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { ensureDir } from '../core/config.js';
|
|
5
|
+
import { HOOK_CONFIGS } from './reminders.js';
|
|
6
|
+
/**
|
|
7
|
+
* Install hook scripts/plugins for the given agent type.
|
|
8
|
+
* This is independent from prompt injection — either can succeed/fail without affecting the other.
|
|
9
|
+
*/
|
|
10
|
+
export async function installHooks(agentType) {
|
|
11
|
+
const home = os.homedir();
|
|
12
|
+
const config = HOOK_CONFIGS[agentType];
|
|
13
|
+
const hookDir = config.getHookDir(home);
|
|
14
|
+
const result = {
|
|
15
|
+
success: false,
|
|
16
|
+
hookDir,
|
|
17
|
+
filesWritten: [],
|
|
18
|
+
settingsUpdated: false,
|
|
19
|
+
notes: [],
|
|
20
|
+
};
|
|
21
|
+
try {
|
|
22
|
+
// Step 1: Generate hook files to target directory
|
|
23
|
+
await ensureDir(hookDir);
|
|
24
|
+
for (const [fileName, content] of Object.entries(config.files)) {
|
|
25
|
+
const filePath = path.join(hookDir, fileName);
|
|
26
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
27
|
+
// Make shell scripts executable
|
|
28
|
+
if (fileName.endsWith('.sh')) {
|
|
29
|
+
await fs.chmod(filePath, 0o755);
|
|
30
|
+
}
|
|
31
|
+
result.filesWritten.push(filePath);
|
|
32
|
+
}
|
|
33
|
+
// Step 2: For Claude Code / Codex, merge hook config into settings.json
|
|
34
|
+
if (config.getSettingsPath) {
|
|
35
|
+
const settingsPath = config.getSettingsPath(home);
|
|
36
|
+
const activatorPath = path.join(hookDir, 'mnemo-activator.sh');
|
|
37
|
+
await mergeHookSettings(settingsPath, activatorPath);
|
|
38
|
+
result.settingsUpdated = true;
|
|
39
|
+
}
|
|
40
|
+
// Step 3: Agent-specific post-install notes
|
|
41
|
+
if (agentType === 'openclaw') {
|
|
42
|
+
result.notes.push('Run `openclaw hooks enable mnemo` to activate the hook.');
|
|
43
|
+
}
|
|
44
|
+
result.success = true;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
result.error = err instanceof Error ? err.message : String(err);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Merge Mnemo hook configuration into a Claude Code / Codex settings.json.
|
|
53
|
+
* Reads existing settings, adds/updates the Mnemo hook entry, writes back.
|
|
54
|
+
* Does not overwrite other existing hooks.
|
|
55
|
+
*/
|
|
56
|
+
async function mergeHookSettings(settingsPath, activatorPath) {
|
|
57
|
+
// Read existing settings or start fresh
|
|
58
|
+
let settings = {};
|
|
59
|
+
try {
|
|
60
|
+
const raw = await fs.readFile(settingsPath, 'utf-8');
|
|
61
|
+
settings = JSON.parse(raw);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// File doesn't exist or is invalid JSON — start fresh
|
|
65
|
+
}
|
|
66
|
+
// Ensure hooks object exists
|
|
67
|
+
if (!settings.hooks || typeof settings.hooks !== 'object') {
|
|
68
|
+
settings.hooks = {};
|
|
69
|
+
}
|
|
70
|
+
const hooks = settings.hooks;
|
|
71
|
+
// Build the Mnemo hook entry
|
|
72
|
+
const mnemoHookEntry = {
|
|
73
|
+
matcher: '',
|
|
74
|
+
hooks: [
|
|
75
|
+
{
|
|
76
|
+
type: 'command',
|
|
77
|
+
command: activatorPath,
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
// Merge into UserPromptSubmit
|
|
82
|
+
if (!Array.isArray(hooks.UserPromptSubmit)) {
|
|
83
|
+
hooks.UserPromptSubmit = [];
|
|
84
|
+
}
|
|
85
|
+
// Remove existing Mnemo entries (identified by command path containing 'mnemo')
|
|
86
|
+
hooks.UserPromptSubmit = hooks.UserPromptSubmit.filter((entry) => {
|
|
87
|
+
if (!entry || typeof entry !== 'object')
|
|
88
|
+
return true;
|
|
89
|
+
const e = entry;
|
|
90
|
+
if (!Array.isArray(e.hooks))
|
|
91
|
+
return true;
|
|
92
|
+
return !e.hooks.some((h) => {
|
|
93
|
+
if (!h || typeof h !== 'object')
|
|
94
|
+
return false;
|
|
95
|
+
const hook = h;
|
|
96
|
+
return typeof hook.command === 'string' && hook.command.includes('mnemo');
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
// Add the new Mnemo entry
|
|
100
|
+
hooks.UserPromptSubmit.push(mnemoHookEntry);
|
|
101
|
+
// Write back
|
|
102
|
+
await ensureDir(path.dirname(settingsPath));
|
|
103
|
+
await fs.writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if hooks are already installed for the given agent type.
|
|
107
|
+
*/
|
|
108
|
+
export async function hasHooksInstalled(agentType) {
|
|
109
|
+
const home = os.homedir();
|
|
110
|
+
const config = HOOK_CONFIGS[agentType];
|
|
111
|
+
const hookDir = config.getHookDir(home);
|
|
112
|
+
try {
|
|
113
|
+
// Check if at least one hook file exists
|
|
114
|
+
for (const fileName of Object.keys(config.files)) {
|
|
115
|
+
await fs.access(path.join(hookDir, fileName));
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// Not installed
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/hooks/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type AgentType } from '../core/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Core reminder texts used across all agents.
|
|
4
|
+
* Keep each reminder minimal (~50 tokens) to avoid attention overhead.
|
|
5
|
+
*/
|
|
6
|
+
export declare const REMINDERS: {
|
|
7
|
+
/** Per-turn self-check reminder (UserPromptSubmit equivalent) */
|
|
8
|
+
readonly perTurn: "<mnemo-reminder>\nAfter this task, briefly self-check:\n- Did a durable preference, decision, or rule emerge? → memory_save\n- Is there an unresolved thread to resume later? → memory_save (continuity)\n- Did context window reset? → memory_compress\nIf nothing qualifies, skip. Don't force saves.\n</mnemo-reminder>";
|
|
9
|
+
/** Session start reminder */
|
|
10
|
+
readonly sessionStart: "<mnemo-session-start>\nSearch memory for relevant context before starting work.\nCall memory_search with a query based on the user's message.\n</mnemo-session-start>";
|
|
11
|
+
/** Context compaction reminder */
|
|
12
|
+
readonly compaction: "<mnemo-compaction>\nContext is being compacted. Before losing context:\n1. Save any important unresolved threads as continuity memories (memory_save)\n2. Call memory_compress if many notes have accumulated\n</mnemo-compaction>";
|
|
13
|
+
/** Session end / idle self-check */
|
|
14
|
+
readonly sessionEnd: "<mnemo-session-end>\nSession ending. Quick self-check:\n- Did a durable conclusion, preference, or decision emerge? → memory_save\n- Was an important thread left unresolved? → memory_save (continuity)\n- Did I learn something reusable that would be lost without saving? → memory_save (experience)\n</mnemo-session-end>";
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Shell script for Claude Code / Codex UserPromptSubmit hook.
|
|
18
|
+
* Outputs the per-turn reminder to stdout so the agent sees it as context.
|
|
19
|
+
*/
|
|
20
|
+
export declare const ACTIVATOR_SCRIPT: string;
|
|
21
|
+
/**
|
|
22
|
+
* OpenClaw HOOK.md manifest for the mnemo hook.
|
|
23
|
+
*/
|
|
24
|
+
export declare const OPENCLAW_HOOK_MD = "---\nname: mnemo\ndescription: \"Injects memory management reminder during agent bootstrap\"\nmetadata: {\"openclaw\":{\"emoji\":\"\\ud83e\\udde0\",\"events\":[\"agent:bootstrap\"]}}\n---\n";
|
|
25
|
+
/**
|
|
26
|
+
* OpenClaw handler.ts for agent:bootstrap event.
|
|
27
|
+
* Injects a virtual MNEMO_REMINDER.md file into the bootstrap context.
|
|
28
|
+
*/
|
|
29
|
+
export declare const OPENCLAW_HANDLER_TS: string;
|
|
30
|
+
/**
|
|
31
|
+
* OpenCode plugin for mnemo memory reminders.
|
|
32
|
+
* Subscribes to session lifecycle events.
|
|
33
|
+
*/
|
|
34
|
+
export declare const OPENCODE_PLUGIN_TS: string;
|
|
35
|
+
interface HookScriptConfig {
|
|
36
|
+
/** Directory where hook files are installed */
|
|
37
|
+
getHookDir: (home: string) => string;
|
|
38
|
+
/** Files to generate: filename → content */
|
|
39
|
+
files: Record<string, string>;
|
|
40
|
+
/**
|
|
41
|
+
* For Claude Code / Codex: path to settings.json that needs hook config merged.
|
|
42
|
+
* For OpenClaw / OpenCode: null (no settings merge needed).
|
|
43
|
+
*/
|
|
44
|
+
getSettingsPath?: (home: string) => string;
|
|
45
|
+
}
|
|
46
|
+
export declare const HOOK_CONFIGS: Record<AgentType, HookScriptConfig>;
|
|
47
|
+
export {};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core reminder texts used across all agents.
|
|
3
|
+
* Keep each reminder minimal (~50 tokens) to avoid attention overhead.
|
|
4
|
+
*/
|
|
5
|
+
export const REMINDERS = {
|
|
6
|
+
/** Per-turn self-check reminder (UserPromptSubmit equivalent) */
|
|
7
|
+
perTurn: `<mnemo-reminder>
|
|
8
|
+
After this task, briefly self-check:
|
|
9
|
+
- Did a durable preference, decision, or rule emerge? → memory_save
|
|
10
|
+
- Is there an unresolved thread to resume later? → memory_save (continuity)
|
|
11
|
+
- Did context window reset? → memory_compress
|
|
12
|
+
If nothing qualifies, skip. Don't force saves.
|
|
13
|
+
</mnemo-reminder>`,
|
|
14
|
+
/** Session start reminder */
|
|
15
|
+
sessionStart: `<mnemo-session-start>
|
|
16
|
+
Search memory for relevant context before starting work.
|
|
17
|
+
Call memory_search with a query based on the user's message.
|
|
18
|
+
</mnemo-session-start>`,
|
|
19
|
+
/** Context compaction reminder */
|
|
20
|
+
compaction: `<mnemo-compaction>
|
|
21
|
+
Context is being compacted. Before losing context:
|
|
22
|
+
1. Save any important unresolved threads as continuity memories (memory_save)
|
|
23
|
+
2. Call memory_compress if many notes have accumulated
|
|
24
|
+
</mnemo-compaction>`,
|
|
25
|
+
/** Session end / idle self-check */
|
|
26
|
+
sessionEnd: `<mnemo-session-end>
|
|
27
|
+
Session ending. Quick self-check:
|
|
28
|
+
- Did a durable conclusion, preference, or decision emerge? → memory_save
|
|
29
|
+
- Was an important thread left unresolved? → memory_save (continuity)
|
|
30
|
+
- Did I learn something reusable that would be lost without saving? → memory_save (experience)
|
|
31
|
+
</mnemo-session-end>`,
|
|
32
|
+
};
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Claude Code / Codex — shell script template
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/**
|
|
37
|
+
* Shell script for Claude Code / Codex UserPromptSubmit hook.
|
|
38
|
+
* Outputs the per-turn reminder to stdout so the agent sees it as context.
|
|
39
|
+
*/
|
|
40
|
+
export const ACTIVATOR_SCRIPT = `#!/bin/bash
|
|
41
|
+
# Mnemo Memory Activator Hook
|
|
42
|
+
# Triggers on UserPromptSubmit to remind the agent about memory management
|
|
43
|
+
# Keep output minimal (~50 tokens) to minimize overhead
|
|
44
|
+
|
|
45
|
+
set -e
|
|
46
|
+
|
|
47
|
+
cat << 'EOF'
|
|
48
|
+
${REMINDERS.perTurn}
|
|
49
|
+
EOF
|
|
50
|
+
`;
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// OpenClaw — HOOK.md + handler.ts templates
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/**
|
|
55
|
+
* OpenClaw HOOK.md manifest for the mnemo hook.
|
|
56
|
+
*/
|
|
57
|
+
export const OPENCLAW_HOOK_MD = `---
|
|
58
|
+
name: mnemo
|
|
59
|
+
description: "Injects memory management reminder during agent bootstrap"
|
|
60
|
+
metadata: {"openclaw":{"emoji":"\\ud83e\\udde0","events":["agent:bootstrap"]}}
|
|
61
|
+
---
|
|
62
|
+
`;
|
|
63
|
+
/**
|
|
64
|
+
* OpenClaw handler.ts for agent:bootstrap event.
|
|
65
|
+
* Injects a virtual MNEMO_REMINDER.md file into the bootstrap context.
|
|
66
|
+
*/
|
|
67
|
+
export const OPENCLAW_HANDLER_TS = `const REMINDER_CONTENT = \`
|
|
68
|
+
## Mnemo - Memory Management Reminder
|
|
69
|
+
|
|
70
|
+
${REMINDERS.sessionStart}
|
|
71
|
+
|
|
72
|
+
${REMINDERS.perTurn}
|
|
73
|
+
\`;
|
|
74
|
+
|
|
75
|
+
const handler = async (event) => {
|
|
76
|
+
// Only handle agent:bootstrap
|
|
77
|
+
if (event.type !== 'agent' || event.action !== 'bootstrap') {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Skip sub-agent sessions to avoid bootstrap issues
|
|
82
|
+
if (event.sessionKey && event.sessionKey.includes(':subagent:')) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Inject virtual file into bootstrap context
|
|
87
|
+
if (Array.isArray(event.context.bootstrapFiles)) {
|
|
88
|
+
event.context.bootstrapFiles.push({
|
|
89
|
+
path: 'MNEMO_REMINDER.md',
|
|
90
|
+
content: REMINDER_CONTENT,
|
|
91
|
+
virtual: true,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export default handler;
|
|
97
|
+
`;
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// OpenCode — plugin template
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
/**
|
|
102
|
+
* OpenCode plugin for mnemo memory reminders.
|
|
103
|
+
* Subscribes to session lifecycle events.
|
|
104
|
+
*/
|
|
105
|
+
export const OPENCODE_PLUGIN_TS = `/**
|
|
106
|
+
* Mnemo Memory Reminder Plugin for OpenCode
|
|
107
|
+
* Injects memory management reminders at key session lifecycle points.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
const SESSION_START_REMINDER = \`${REMINDERS.sessionStart}\`;
|
|
111
|
+
|
|
112
|
+
const SESSION_END_REMINDER = \`${REMINDERS.sessionEnd}\`;
|
|
113
|
+
|
|
114
|
+
const COMPACTION_REMINDER = \`${REMINDERS.compaction}\`;
|
|
115
|
+
|
|
116
|
+
export const MnemoReminder = async ({ client }) => {
|
|
117
|
+
return {
|
|
118
|
+
event: async ({ event }) => {
|
|
119
|
+
if (event.type === "session.created") {
|
|
120
|
+
// Remind to search memory at session start
|
|
121
|
+
try {
|
|
122
|
+
const sessions = await client.session.list();
|
|
123
|
+
const current = sessions.data?.[0];
|
|
124
|
+
if (current?.id) {
|
|
125
|
+
await client.session.prompt({
|
|
126
|
+
path: { id: current.id },
|
|
127
|
+
body: {
|
|
128
|
+
noReply: true,
|
|
129
|
+
parts: [{ type: "text", text: SESSION_START_REMINDER }],
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
// Best effort — don't break the session
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (event.type === "session.idle") {
|
|
138
|
+
// Remind to self-check at session end
|
|
139
|
+
try {
|
|
140
|
+
const sessions = await client.session.list();
|
|
141
|
+
const current = sessions.data?.[0];
|
|
142
|
+
if (current?.id) {
|
|
143
|
+
await client.session.prompt({
|
|
144
|
+
path: { id: current.id },
|
|
145
|
+
body: {
|
|
146
|
+
noReply: true,
|
|
147
|
+
parts: [{ type: "text", text: SESSION_END_REMINDER }],
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
} catch {
|
|
152
|
+
// Best effort
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"experimental.session.compacting": async (input, output) => {
|
|
157
|
+
output.context.push(COMPACTION_REMINDER);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
`;
|
|
162
|
+
export const HOOK_CONFIGS = {
|
|
163
|
+
'claude-code': {
|
|
164
|
+
getHookDir: (home) => `${home}/.claude/hooks/mnemo`,
|
|
165
|
+
files: {
|
|
166
|
+
'mnemo-activator.sh': ACTIVATOR_SCRIPT,
|
|
167
|
+
},
|
|
168
|
+
getSettingsPath: (home) => `${home}/.claude/settings.json`,
|
|
169
|
+
},
|
|
170
|
+
codex: {
|
|
171
|
+
getHookDir: (home) => `${home}/.codex/hooks/mnemo`,
|
|
172
|
+
files: {
|
|
173
|
+
'mnemo-activator.sh': ACTIVATOR_SCRIPT,
|
|
174
|
+
},
|
|
175
|
+
getSettingsPath: (home) => `${home}/.codex/settings.json`,
|
|
176
|
+
},
|
|
177
|
+
openclaw: {
|
|
178
|
+
getHookDir: (home) => `${home}/.openclaw/hooks/mnemo`,
|
|
179
|
+
files: {
|
|
180
|
+
'HOOK.md': OPENCLAW_HOOK_MD,
|
|
181
|
+
'handler.ts': OPENCLAW_HANDLER_TS,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
opencode: {
|
|
185
|
+
getHookDir: (home) => `${home}/.config/opencode/plugins`,
|
|
186
|
+
files: {
|
|
187
|
+
'mnemo-reminder.ts': OPENCODE_PLUGIN_TS,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=reminders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reminders.js","sourceRoot":"","sources":["../../src/hooks/reminders.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG;IACrB,iEAAiE;IACjE,OAAO,EAAE;;;;;;kBAMK;IAEd,6BAA6B;IAC7B,YAAY,EAAE;;;uBAGK;IAEnB,kCAAkC;IAClC,UAAU,EAAE;;;;oBAII;IAEhB,oCAAoC;IACpC,UAAU,EAAE;;;;;qBAKK;CACX,CAAC;AAEX,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;EAQ9B,SAAS,CAAC,OAAO;;CAElB,CAAC;AAEF,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;CAK/B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;EAGjC,SAAS,CAAC,YAAY;;EAEtB,SAAS,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlB,CAAC;AAEF,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;mCAKC,SAAS,CAAC,YAAY;;iCAExB,SAAS,CAAC,UAAU;;gCAErB,SAAS,CAAC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CnD,CAAC;AAkBF,MAAM,CAAC,MAAM,YAAY,GAAwC;IAC7D,aAAa,EAAE;QACX,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,sBAAsB;QACnD,KAAK,EAAE;YACH,oBAAoB,EAAE,gBAAgB;SACzC;QACD,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,wBAAwB;KAC7D;IACD,KAAK,EAAE;QACH,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,qBAAqB;QAClD,KAAK,EAAE;YACH,oBAAoB,EAAE,gBAAgB;SACzC;QACD,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,uBAAuB;KAC5D;IACD,QAAQ,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,wBAAwB;QACrD,KAAK,EAAE;YACH,SAAS,EAAE,gBAAgB;YAC3B,YAAY,EAAE,mBAAmB;SACpC;KACJ;IACD,QAAQ,EAAE;QACN,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,2BAA2B;QACxD,KAAK,EAAE;YACH,mBAAmB,EAAE,kBAAkB;SAC1C;KACJ;CACJ,CAAC"}
|
|
@@ -8,15 +8,63 @@ You have access to a persistent memory system (Mnemo). Use it to retain importan
|
|
|
8
8
|
|
|
9
9
|
Mnemo is not a full transcript archive. It is a system for preserving high-value long-term context across conversations.
|
|
10
10
|
|
|
11
|
+
### Quick Reference
|
|
12
|
+
|
|
13
|
+
| Situation | Action | Type |
|
|
14
|
+
|-----------|--------|------|
|
|
15
|
+
| User states a stable preference or working style | memory_save | preference |
|
|
16
|
+
| A decision is made that will affect future work | memory_save | decision |
|
|
17
|
+
| A reusable rule or convention is established | memory_save | rule |
|
|
18
|
+
| A long-term goal or direction is clarified | memory_save | goal |
|
|
19
|
+
| An unresolved thread must be resumed later | memory_save | continuity |
|
|
20
|
+
| Stable background info about user/project/topic | memory_save | profile or fact |
|
|
21
|
+
| A validated, reusable experience proves its worth | memory_save | experience |
|
|
22
|
+
| New conversation begins | memory_search | — |
|
|
23
|
+
| User references past discussions or decisions | memory_search | — |
|
|
24
|
+
| Entering a long-running project or topic | memory_search | — |
|
|
25
|
+
| Many notes accumulated or context window reset | memory_compress | — |
|
|
26
|
+
| A continuity thread has been resolved | memory_compress or memory_save | evolve type |
|
|
27
|
+
|
|
28
|
+
### When to search memory (memory_search):
|
|
29
|
+
- **At the START of each conversation**, search for relevant context based on the user's first message. This is your highest-priority Mnemo action — do it before anything else.
|
|
30
|
+
- Search before doing major work on an ongoing topic, project, or long-running discussion
|
|
31
|
+
- When the user references past discussions or decisions — watch for phrases like:
|
|
32
|
+
- "do you remember...", "we discussed before...", "last time we..."
|
|
33
|
+
- "didn't we decide...", "what was the conclusion on..."
|
|
34
|
+
- "as we agreed...", "going back to..."
|
|
35
|
+
- When you need background context for a task
|
|
36
|
+
- memory_search returns **summaries** — use memory_get with the returned IDs to retrieve full content when needed
|
|
37
|
+
|
|
11
38
|
### When to save memory (memory_save):
|
|
12
39
|
- Save only high-value long-term context, not temporary details or full conversation logs
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
40
|
+
- Watch for these trigger patterns in conversation:
|
|
41
|
+
|
|
42
|
+
**Preferences** (→ type: preference):
|
|
43
|
+
- User says: "I prefer...", "always do it this way...", "don't ever...", "I like when..."
|
|
44
|
+
- User expresses a stable preference, working style, boundary, or requirement
|
|
45
|
+
|
|
46
|
+
**Decisions** (→ type: decision):
|
|
47
|
+
- User says: "let's go with...", "decided:", "the plan is...", "we'll use..."
|
|
48
|
+
- A question is resolved and the answer will affect future work
|
|
49
|
+
|
|
50
|
+
**Rules** (→ type: rule):
|
|
51
|
+
- User says: "from now on...", "going forward, always...", "the convention is..."
|
|
52
|
+
- A reusable workflow convention or agreement is established
|
|
53
|
+
|
|
54
|
+
**Goals** (→ type: goal):
|
|
55
|
+
- User says: "the long-term plan is...", "eventually we want...", "the vision is..."
|
|
56
|
+
- A long-term direction or objective is clarified
|
|
57
|
+
|
|
58
|
+
**Continuity** (→ type: continuity):
|
|
59
|
+
- A thread is left unresolved but will clearly be resumed
|
|
60
|
+
- User says: "we'll pick this up later...", "let's come back to this...", "not now, but..."
|
|
61
|
+
|
|
62
|
+
**Profile / Fact** (→ type: profile or fact):
|
|
63
|
+
- Stable background information about the user, project, or topic is surfaced
|
|
64
|
+
|
|
65
|
+
**Experience** (→ type: experience) — high bar:
|
|
66
|
+
- Only save when ALL three conditions are met: (1) the experience has been validated, (2) it is reusable across sessions, (3) it would meaningfully affect future work
|
|
67
|
+
- A single error, one-off debugging session, or unconfirmed workaround does NOT qualify
|
|
20
68
|
|
|
21
69
|
### When to initialize memory (memory_setup):
|
|
22
70
|
- When Mnemo has not been initialized yet and a memory tool reports that setup is required
|
|
@@ -24,14 +72,6 @@ Mnemo is not a full transcript archive. It is a system for preserving high-value
|
|
|
24
72
|
- Default to global scope for shared cross-project memory
|
|
25
73
|
- Use project scope only when the user explicitly wants isolated per-project memory
|
|
26
74
|
|
|
27
|
-
### When to search memory (memory_search):
|
|
28
|
-
- At the START of each conversation, search for relevant context based on the user's first message
|
|
29
|
-
- Search before doing major work on an ongoing topic, project, or long-running discussion
|
|
30
|
-
- When the user references past discussions or decisions
|
|
31
|
-
- When you need background context for a task
|
|
32
|
-
- When the user asks "do you remember..." or similar
|
|
33
|
-
- memory_search returns **summaries** — use memory_get with the returned IDs to retrieve full content when needed
|
|
34
|
-
|
|
35
75
|
### When to get full memory content (memory_get):
|
|
36
76
|
- After memory_search, when you need the complete content of specific memories
|
|
37
77
|
- Pass one or more note IDs from memory_search results to retrieve full content
|
|
@@ -45,17 +85,34 @@ Mnemo is not a full transcript archive. It is a system for preserving high-value
|
|
|
45
85
|
- When a continuity thread has turned into a clear decision, rule, or fact and older notes should be consolidated
|
|
46
86
|
- Workflow: call memory_compress to get all notes → distill them into fewer, concise notes → call memory_compress_apply with the distilled notes and old IDs to atomically save new + delete old
|
|
47
87
|
|
|
88
|
+
### Memory Lifecycle:
|
|
89
|
+
Memories are not static. They evolve as context matures:
|
|
90
|
+
- \`continuity\` → \`decision\` (when an open question is resolved)
|
|
91
|
+
- \`decision\` → \`rule\` (when a one-time choice becomes a standing convention)
|
|
92
|
+
- \`continuity\` → \`fact\` (when an open question is answered with stable info)
|
|
93
|
+
- \`experience\` → \`rule\` (when a validated experience becomes a default practice)
|
|
94
|
+
|
|
95
|
+
**Continuity closure**: When a \`continuity\` thread is resolved, do not leave it dangling — either transform it into the appropriate type (decision, fact, rule) or remove it if it no longer has long-term value. Stale continuity notes pollute the memory system.
|
|
96
|
+
|
|
97
|
+
**Dedup before adding**: When saving, always check if a similar memory already exists. Prefer updating or replacing existing memories over creating duplicates. Priority order: supplement existing → update existing → replace outdated → add new (last resort).
|
|
98
|
+
|
|
48
99
|
### Guidelines:
|
|
49
100
|
- Prefer this order: memory_search -> do the work -> memory_save -> memory_compress when needed
|
|
50
101
|
- Before saving, verify the information meets at least 2 of these 3 criteria: (1) useful across future sessions, (2) affects future work or decisions, (3) would require re-alignment if forgotten
|
|
51
|
-
- Before saving new content, check if a similar memory already exists. Prefer updating or replacing existing memories over creating duplicates.
|
|
52
102
|
- **Always specify a type when saving.** Determine the type first (preference, profile, goal, continuity, fact, decision, rule, or experience), then call memory_save with the type parameter. Saving without a type defeats the purpose of organized long-term memory.
|
|
53
|
-
- Save memories in concise, distilled form
|
|
103
|
+
- Save memories in concise, distilled form — capture the essence, not raw conversation
|
|
54
104
|
- Do not save routine task state, ordinary command output, or one-off debugging noise
|
|
55
105
|
- Use descriptive tags to categorize memories
|
|
56
106
|
- Always include relevant project/topic context in the memory content
|
|
57
107
|
- Do not save trivial or temporary information
|
|
58
108
|
- When searching, use semantic queries that describe the information you need
|
|
109
|
+
|
|
110
|
+
### Self-Check (after completing each task):
|
|
111
|
+
Ask yourself briefly:
|
|
112
|
+
- Did a durable conclusion, preference, or decision emerge from this conversation?
|
|
113
|
+
- Was an important thread left unresolved that I should save as continuity?
|
|
114
|
+
- Did I learn something reusable that would be lost without saving?
|
|
115
|
+
If the answer to any of these is yes and the save threshold is met, call memory_save before moving on.
|
|
59
116
|
`.trim();
|
|
60
117
|
/**
|
|
61
118
|
* Agent-specific memory prompt overrides.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/prompts/templates.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,kBAAkB,GAAG
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/prompts/templates.ts"],"names":[],"mappings":"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"}
|
package/build/tools/setup.js
CHANGED
|
@@ -4,14 +4,26 @@ import path from 'node:path';
|
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
5
|
import { promisify } from 'node:util';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { AGENT_TYPES, writeStorageConfig } from '../core/config.js';
|
|
7
|
+
import { AGENT_TYPES, CLIENT_NAME_MAP, writeStorageConfig } from '../core/config.js';
|
|
8
8
|
import { getAgentConfig, injectPrompt, hasPromptInjected } from '../prompts/templates.js';
|
|
9
|
+
import { installHooks } from '../hooks/installer.js';
|
|
9
10
|
const execFileAsync = promisify(execFile);
|
|
10
11
|
const PROJECT_ROOT_MARKERS = ['.git', 'package.json', 'pyproject.toml', 'Cargo.toml', 'go.mod'];
|
|
11
12
|
/**
|
|
12
|
-
* Detect
|
|
13
|
+
* Detect agent type from MCP protocol clientInfo.
|
|
14
|
+
* The initialize handshake includes clientInfo.name which authoritatively identifies the client.
|
|
13
15
|
*/
|
|
14
|
-
|
|
16
|
+
function detectAgentTypeFromClient(server) {
|
|
17
|
+
const clientInfo = server.server.getClientVersion();
|
|
18
|
+
if (!clientInfo?.name)
|
|
19
|
+
return null;
|
|
20
|
+
return CLIENT_NAME_MAP[clientInfo.name] ?? null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Detect which agent tool is being used by checking config file existence.
|
|
24
|
+
* Used as fallback when MCP protocol-level detection is not available.
|
|
25
|
+
*/
|
|
26
|
+
async function detectAgentTypeFromFiles(cwd) {
|
|
15
27
|
const home = os.homedir();
|
|
16
28
|
// Check for agent-specific config files
|
|
17
29
|
const checks = [
|
|
@@ -116,22 +128,28 @@ export function registerSetupTool(server) {
|
|
|
116
128
|
}, async ({ agent_type, scope, project_root }) => {
|
|
117
129
|
const cwd = process.cwd();
|
|
118
130
|
const home = os.homedir();
|
|
119
|
-
// Determine agent type
|
|
131
|
+
// Determine agent type: explicit param > MCP protocol > file-based detection
|
|
120
132
|
let agentType = agent_type;
|
|
121
133
|
if (!agentType) {
|
|
122
|
-
const
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
const fromClient = detectAgentTypeFromClient(server);
|
|
135
|
+
if (fromClient) {
|
|
136
|
+
agentType = fromClient;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const fromFiles = await detectAgentTypeFromFiles(cwd);
|
|
140
|
+
if (!fromFiles) {
|
|
141
|
+
return {
|
|
142
|
+
content: [
|
|
143
|
+
{
|
|
144
|
+
type: 'text',
|
|
145
|
+
text: `Could not auto-detect agent type. Please specify agent_type parameter. Valid values: ${AGENT_TYPES.join(', ')}`,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
isError: true,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
agentType = fromFiles;
|
|
133
152
|
}
|
|
134
|
-
agentType = detected;
|
|
135
153
|
}
|
|
136
154
|
const config = getAgentConfig(agentType);
|
|
137
155
|
const projectRoot = scope === 'project' ? await resolveProjectRoot(cwd, project_root) : null;
|
|
@@ -146,31 +164,51 @@ export function registerSetupTool(server) {
|
|
|
146
164
|
catch {
|
|
147
165
|
// File doesn't exist yet, that's fine
|
|
148
166
|
}
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
// Update in place
|
|
152
|
-
const updated = injectPrompt(existingContent, agentType);
|
|
153
|
-
await fs.writeFile(targetPath, updated, 'utf-8');
|
|
154
|
-
return {
|
|
155
|
-
content: [
|
|
156
|
-
{
|
|
157
|
-
type: 'text',
|
|
158
|
-
text: `Mnemo memory instructions updated successfully.\n\nAgent type: ${agentType}\nPrompt scope: ${scope}\nPrompt file: ${targetPath}\nStorage scope: ${scope}\nStorage path: ${storagePath}`,
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
// Inject prompt
|
|
167
|
+
// --- Step 1: Prompt injection ---
|
|
168
|
+
const isUpdate = hasPromptInjected(existingContent);
|
|
164
169
|
const updated = injectPrompt(existingContent, agentType);
|
|
165
170
|
// Ensure parent directory exists
|
|
166
171
|
const dir = targetPath.substring(0, targetPath.lastIndexOf('/'));
|
|
167
172
|
await fs.mkdir(dir, { recursive: true });
|
|
168
173
|
await fs.writeFile(targetPath, updated, 'utf-8');
|
|
174
|
+
const promptStatus = isUpdate ? 'updated' : 'installed';
|
|
175
|
+
// --- Step 2: Hook installation (independent from prompt) ---
|
|
176
|
+
const hookResult = await installHooks(agentType);
|
|
177
|
+
// --- Build report ---
|
|
178
|
+
const lines = [
|
|
179
|
+
isUpdate
|
|
180
|
+
? 'Mnemo memory instructions updated successfully.'
|
|
181
|
+
: 'Mnemo memory management initialized successfully.',
|
|
182
|
+
'',
|
|
183
|
+
`Agent type: ${agentType}`,
|
|
184
|
+
`Prompt: ${promptStatus} → ${targetPath}`,
|
|
185
|
+
`Storage scope: ${scope}`,
|
|
186
|
+
`Storage path: ${storagePath}`,
|
|
187
|
+
];
|
|
188
|
+
if (hookResult.success) {
|
|
189
|
+
lines.push('');
|
|
190
|
+
lines.push(`Hooks: installed → ${hookResult.hookDir}`);
|
|
191
|
+
if (hookResult.settingsUpdated) {
|
|
192
|
+
lines.push('Hook settings: merged into agent settings.json');
|
|
193
|
+
}
|
|
194
|
+
for (const note of hookResult.notes) {
|
|
195
|
+
lines.push(`Note: ${note}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
lines.push('');
|
|
200
|
+
lines.push(`Hooks: failed — ${hookResult.error}`);
|
|
201
|
+
lines.push('Prompt injection succeeded independently. Hooks can be retried later.');
|
|
202
|
+
}
|
|
203
|
+
if (!isUpdate) {
|
|
204
|
+
lines.push('');
|
|
205
|
+
lines.push('Mnemo is now ready to use.');
|
|
206
|
+
}
|
|
169
207
|
return {
|
|
170
208
|
content: [
|
|
171
209
|
{
|
|
172
210
|
type: 'text',
|
|
173
|
-
text:
|
|
211
|
+
text: lines.join('\n'),
|
|
174
212
|
},
|
|
175
213
|
],
|
|
176
214
|
};
|
package/build/tools/setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/tools/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAkB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/tools/setup.ts"],"names":[],"mappings":"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"}
|