mr-memory 1.0.7 → 1.0.9

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/index.ts CHANGED
@@ -9,10 +9,43 @@
9
9
  */
10
10
 
11
11
  import { spawn } from "node:child_process";
12
- import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
13
12
 
14
13
  const DEFAULT_ENDPOINT = "https://api.memoryrouter.ai";
15
14
 
15
+ /**
16
+ * Minimal type surface for the OpenClaw plugin host API.
17
+ * Defined locally so this plugin compiles standalone without an
18
+ * `openclaw` dev-dependency — the real object is injected at runtime.
19
+ */
20
+ interface CliCommand {
21
+ command(name: string): CliCommand;
22
+ description(desc: string): CliCommand;
23
+ argument(flags: string, desc?: string): CliCommand;
24
+ option(flags: string, desc?: string): CliCommand;
25
+ action(fn: (...args: never[]) => unknown): CliCommand;
26
+ help(): void;
27
+ }
28
+
29
+ type OpenClawPluginApi = {
30
+ id: string;
31
+ config: Record<string, unknown> & {
32
+ workspace?: string;
33
+ agents?: { defaults?: { workspace?: string } };
34
+ };
35
+ pluginConfig: unknown;
36
+ logger: { info?: (...args: unknown[]) => void };
37
+ registerStreamFnWrapper: (
38
+ wrapper: (
39
+ next: (model: Record<string, unknown>, context: unknown, options?: Record<string, unknown>) => unknown,
40
+ ) => (model: Record<string, unknown>, context: unknown, options?: Record<string, unknown>) => unknown,
41
+ ) => void;
42
+ registerCli: (
43
+ setup: (ctx: { program: CliCommand }) => void,
44
+ opts?: { commands?: string[] },
45
+ ) => void;
46
+ registerService: (svc: { id: string; start: () => void; stop: () => void }) => void;
47
+ };
48
+
16
49
  type MemoryRouterConfig = {
17
50
  key: string;
18
51
  endpoint?: string;
package/package.json CHANGED
@@ -1,8 +1,14 @@
1
1
  {
2
2
  "name": "mr-memory",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "MemoryRouter persistent memory plugin for OpenClaw — your AI remembers every conversation",
5
5
  "type": "module",
6
+ "files": [
7
+ "README.md",
8
+ "index.ts",
9
+ "openclaw.plugin.json",
10
+ "upload.ts"
11
+ ],
6
12
  "keywords": [
7
13
  "openclaw",
8
14
  "openclaw-plugin",
@@ -20,6 +26,10 @@
20
26
  "directory": "integrations/openclaw-plugin"
21
27
  },
22
28
  "homepage": "https://memoryrouter.ai/openclaw",
29
+ "dependencies": {
30
+ "pdf-parse": "^1.1.1",
31
+ "mammoth": "^1.8.0"
32
+ },
23
33
  "openclaw": {
24
34
  "extensions": [
25
35
  "./index.ts"
package/upload.ts CHANGED
@@ -46,8 +46,30 @@ function chunkText(text: string, targetChars: number): string[] {
46
46
  return chunks;
47
47
  }
48
48
 
49
+ const BINARY_EXTENSIONS = new Set([".pdf", ".docx"]);
50
+ const DOC_EXTENSIONS = new Set([".md", ".pdf", ".docx"]);
51
+
52
+ async function extractText(filePath: string): Promise<string> {
53
+ const ext = path.extname(filePath).toLowerCase();
54
+ try {
55
+ if (ext === ".pdf") {
56
+ const pdfParse = (await import("pdf-parse")).default;
57
+ const buffer = await fs.readFile(filePath);
58
+ return (await pdfParse(buffer)).text;
59
+ }
60
+ if (ext === ".docx") {
61
+ const mammoth = await import("mammoth");
62
+ return (await mammoth.extractRawText({ path: filePath })).value;
63
+ }
64
+ } catch (err) {
65
+ console.error(` ⚠ Failed to extract ${path.basename(filePath)}: ${err instanceof Error ? err.message : err}`);
66
+ return "";
67
+ }
68
+ return fs.readFile(filePath, "utf-8");
69
+ }
70
+
49
71
  async function fileToJsonl(filePath: string): Promise<MemoryLine[]> {
50
- const content = await fs.readFile(filePath, "utf-8");
72
+ const content = await extractText(filePath);
51
73
  const stat = await fs.stat(filePath);
52
74
  const timestamp = Math.floor(stat.mtimeMs);
53
75
  const filename = path.basename(filePath);
@@ -127,7 +149,10 @@ async function discoverWorkspaceFiles(workspacePath: string): Promise<string[]>
127
149
  const memoryDir = path.join(workspacePath, "memory");
128
150
  if (await exists(memoryDir)) {
129
151
  const allMemFiles = await fs.readdir(memoryDir, { recursive: true });
130
- const mdFiles = (allMemFiles as string[]).filter((f) => f.endsWith(".md"));
152
+ const mdFiles = (allMemFiles as string[]).filter((f) => {
153
+ const ext = path.extname(f).toLowerCase();
154
+ return DOC_EXTENSIONS.has(ext);
155
+ });
131
156
  files.push(...mdFiles.map((f) => path.join(memoryDir, f)));
132
157
  }
133
158
 
@@ -201,7 +226,10 @@ export async function runUpload(params: {
201
226
  if (stat.isDirectory()) {
202
227
  const allDirFiles = await fs.readdir(resolved, { recursive: true });
203
228
  files = (allDirFiles as string[])
204
- .filter((f) => f.endsWith(".md") || f.endsWith(".jsonl"))
229
+ .filter((f) => {
230
+ const ext = path.extname(f).toLowerCase();
231
+ return DOC_EXTENSIONS.has(ext) || ext === ".jsonl";
232
+ })
205
233
  .map((f) => path.join(resolved, f));
206
234
  } else {
207
235
  files = [resolved];
Binary file