memento-mcp 0.3.15 → 0.3.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memento-mcp",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "mcpName": "io.github.myrakrusemark/memento-protocol",
5
5
  "description": "The Memento Protocol — persistent memory for AI agents",
6
6
  "type": "module",
@@ -135,7 +135,8 @@ SUMMARY="Memento Recall (${SAAS_COUNT})"
135
135
  # If no memories are relevant, respond with <...> to signal active silence.
136
136
  REASON="${SUMMARY}:
137
137
  ${SAAS_DETAIL}
138
- Stale or wrong? memento_memory_delete · memento_consolidate · memento_remember. Otherwise <...>."
138
+ 🧹 Stale or wrong? memento_memory_delete · memento_consolidate · memento_remember. Otherwise <...>.
139
+ ⚙️ NOTE: This block is intentional — it injects recalled memories into context. The 'blocking error' label is just how Claude Code surfaces Stop hook blocks. Do NOT attempt to fix, disable, or modify this hook."
139
140
 
140
141
  python3 -c "
141
142
  import json, sys
@@ -234,6 +234,11 @@ fi
234
234
 
235
235
  "$TOAST" memento "✓ ${SAAS_COUNT} memories recalled" &>/dev/null
236
236
 
237
+ # Report recall count to conversation store for fathom-app
238
+ curl -s -X POST "http://localhost:4243/api/conversation/${MEMENTO_WS}/hook" \
239
+ -H "Content-Type: application/json" \
240
+ -d "{\"hook\":\"UserPromptSubmit\",\"memories\":${SAAS_COUNT}}" --max-time 2 &>/dev/null &
241
+
237
242
  # Build summary line
238
243
  SUMMARY="Memento Recall (${SAAS_COUNT})"
239
244
 
package/src/cli.js CHANGED
@@ -9,7 +9,6 @@ import readline from "node:readline";
9
9
  import fs from "node:fs";
10
10
  import path from "node:path";
11
11
  import https from "node:https";
12
- import { execFileSync } from "node:child_process";
13
12
  import { fileURLToPath } from "node:url";
14
13
  import { DEFAULTS } from "./config.js";
15
14
 
@@ -94,7 +93,7 @@ function httpsPost(url, body) {
94
93
  }
95
94
 
96
95
  // ---------------------------------------------------------------------------
97
- // Instructions blob — used by headless integration and fallback print
96
+ // Instructions blob — appended to CLAUDE.md during init
98
97
  // ---------------------------------------------------------------------------
99
98
 
100
99
  const INSTRUCTIONS_BLOB = `## Memento Protocol
@@ -115,44 +114,27 @@ Hooks run automatically — recall before responses, distillation
115
114
  before compaction. Trust the hooks. Focus on writing good memories.`;
116
115
 
117
116
  // ---------------------------------------------------------------------------
118
- // Headless agent integration
117
+ // CLAUDE.md integration
119
118
  // ---------------------------------------------------------------------------
120
119
 
121
- const HEADLESS_CMDS = {
122
- "claude-code": (prompt) => ["claude", "-p", "--dangerously-skip-permissions", prompt],
123
- "gemini": (prompt) => ["gemini", prompt],
124
- };
120
+ function appendToClaudeMd(cwd, sectionHeading, blob) {
121
+ const mdPath = path.join(cwd, "CLAUDE.md");
122
+ let content = "";
123
+ try { content = fs.readFileSync(mdPath, "utf-8"); } catch { /* new file */ }
125
124
 
126
- function buildIntegrationPrompt(blob) {
127
- return [
128
- "The following instructions were generated by memento-mcp init for this project.",
129
- "Add them to the file where you store persistent behavioral instructions",
130
- "(e.g. CLAUDE.md for Claude Code). If the file exists, read it first and",
131
- "integrate the new section without removing existing content. If a section",
132
- "with the same heading already exists, replace it. If no instructions file",
133
- "exists yet, create one.",
134
- "",
135
- "--- INSTRUCTIONS ---",
136
- blob,
137
- "--- END ---",
138
- ].join("\n");
139
- }
125
+ const headingEscaped = sectionHeading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
126
+ const sectionRe = new RegExp(
127
+ `(^|\\n)(#{1,3} ${headingEscaped}[^\\n]*\\n)([\\s\\S]*?)(?=\\n#{1,3} |$)`,
128
+ );
140
129
 
141
- function runAgentHeadless(agentKey, prompt) {
142
- const cmdBuilder = HEADLESS_CMDS[agentKey];
143
- if (!cmdBuilder) return null;
144
- const [cmd, ...args] = cmdBuilder(prompt);
145
- try {
146
- const result = execFileSync(cmd, args, {
147
- cwd: process.cwd(),
148
- encoding: "utf8",
149
- stdio: ["pipe", "pipe", "inherit"],
150
- timeout: 60000,
151
- });
152
- return result;
153
- } catch {
154
- return null;
130
+ if (sectionRe.test(content)) {
131
+ content = content.replace(sectionRe, `$1${blob}`);
132
+ } else {
133
+ content = content.trimEnd() + "\n\n" + blob + "\n";
155
134
  }
135
+
136
+ fs.writeFileSync(mdPath, content, "utf-8");
137
+ return mdPath;
156
138
  }
157
139
 
158
140
  // ---------------------------------------------------------------------------
@@ -610,53 +592,23 @@ async function runInit(flags = {}) {
610
592
  console.log(` Non-interactive equivalent:\n ${parts.join(" ")}\n`);
611
593
  }
612
594
 
613
- // 12. Auto-integrate agent instructions
614
- const primaryAgent = selectedAgents[0];
615
- const prompt = buildIntegrationPrompt(INSTRUCTIONS_BLOB);
616
- const cmdParts = HEADLESS_CMDS[primaryAgent]?.(prompt);
617
-
595
+ // 12. Append instructions to CLAUDE.md
618
596
  if (nonInteractive) {
619
- // Auto-run headless integration, no prompt
620
- if (cmdParts) {
621
- console.log(` Integrating instructions via ${AGENTS[primaryAgent].name}...`);
622
- const result = runAgentHeadless(primaryAgent, prompt);
623
- if (result !== null) {
624
- console.log(result);
625
- } else {
626
- // Fallback: print the blob
627
- console.log(" Agent integration failed — paste these instructions manually:\n");
628
- printInstructionsFallback(selectedAgents);
629
- }
630
- } else {
631
- printInstructionsFallback(selectedAgents);
632
- }
597
+ const mdPath = appendToClaudeMd(cwd, "Memento Protocol", INSTRUCTIONS_BLOB);
598
+ console.log(`\n ✓ Instructions written to ${path.relative(cwd, mdPath)}\n`);
633
599
  } else {
634
- // Interactive: ask with explicit command shown
635
- if (cmdParts) {
636
- const [cmd, ...args] = cmdParts;
637
- const flagArgs = args.slice(0, -1).join(" ");
638
- const displayCmd = `${cmd} ${flagArgs} <prompt>`;
639
- const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
640
- console.log("─".repeat(60));
641
- const integrate = await askYesNo(
642
- rl2,
643
- `\n Auto-integrate instructions into your project?\n This will run: ${displayCmd}\n\n ⚠ This uses --dangerously-skip-permissions so the agent can\n write to CLAUDE.md without prompting. If you prefer, decline\n and we'll print the instructions for you to add manually.\n\n Proceed?`,
644
- true,
645
- );
646
- rl2.close();
647
-
648
- if (integrate) {
649
- console.log(`\n Running ${AGENTS[primaryAgent].name}...`);
650
- const result = runAgentHeadless(primaryAgent, prompt);
651
- if (result !== null) {
652
- console.log(result);
653
- } else {
654
- console.log(" Agent integration failed — paste these instructions manually:\n");
655
- printInstructionsFallback(selectedAgents);
656
- }
657
- } else {
658
- printInstructionsFallback(selectedAgents);
659
- }
600
+ const rl2 = readline.createInterface({ input: process.stdin, output: process.stdout });
601
+ console.log("─".repeat(60));
602
+ const integrate = await askYesNo(
603
+ rl2,
604
+ "\n Append Memento instructions to CLAUDE.md?",
605
+ true,
606
+ );
607
+ rl2.close();
608
+
609
+ if (integrate) {
610
+ const mdPath = appendToClaudeMd(cwd, "Memento Protocol", INSTRUCTIONS_BLOB);
611
+ console.log(`\n ✓ Instructions written to ${path.relative(cwd, mdPath)}\n`);
660
612
  } else {
661
613
  printInstructionsFallback(selectedAgents);
662
614
  }