openclaw-molymemos 1.0.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 +121 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/openclaw.plugin.json +26 -0
- package/dist/server-client.d.ts +49 -0
- package/dist/server-client.d.ts.map +1 -0
- package/dist/server-client.js +124 -0
- package/dist/server-client.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# MolyMemos OpenClaw Plugin
|
|
2
|
+
|
|
3
|
+
OpenClaw 插件,通过 WebSocket 连接到服务器,接收推送的内容并写入 memory 文件夹。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 配置
|
|
13
|
+
|
|
14
|
+
在 OpenClaw 配置文件中添加插件配置:
|
|
15
|
+
|
|
16
|
+
```json5
|
|
17
|
+
{
|
|
18
|
+
plugins: {
|
|
19
|
+
entries: {
|
|
20
|
+
"molymemos": {
|
|
21
|
+
enabled: true,
|
|
22
|
+
config: {
|
|
23
|
+
serverUrl: "ws://localhost:8080", // 必填,WebSocket 服务器地址
|
|
24
|
+
apiKey: "your-api-key", // 可选,认证密钥
|
|
25
|
+
reconnectInterval: 5000 // 可选,重连间隔(ms),默认 5000
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 配置项
|
|
34
|
+
|
|
35
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
36
|
+
|------|------|------|------|
|
|
37
|
+
| `serverUrl` | string | 是 | WebSocket 服务器地址 |
|
|
38
|
+
| `apiKey` | string | 否 | API 认证密钥 |
|
|
39
|
+
| `reconnectInterval` | number | 否 | 重连间隔(ms),默认 5000 |
|
|
40
|
+
|
|
41
|
+
## 工作原理
|
|
42
|
+
|
|
43
|
+
1. 插件启动时建立 WebSocket 连接到配置的服务器
|
|
44
|
+
2. 监听服务器推送的消息
|
|
45
|
+
3. 收到消息后将内容 append 到 `{workspaceDir}/memory/molymemos/{filepath}`
|
|
46
|
+
4. 连接断开后自动重连
|
|
47
|
+
|
|
48
|
+
## 服务器消息格式
|
|
49
|
+
|
|
50
|
+
服务器推送的消息需要符合以下 JSON 格式:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"type": "memo",
|
|
55
|
+
"content": "要追加的内容",
|
|
56
|
+
"filepath": "notes/daily.md"
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 接口
|
|
61
|
+
|
|
62
|
+
### Gateway RPC 方法
|
|
63
|
+
|
|
64
|
+
#### `molymemos.append`
|
|
65
|
+
|
|
66
|
+
手动追加内容到文件。
|
|
67
|
+
|
|
68
|
+
参数:
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"content": "要追加的内容",
|
|
72
|
+
"filepath": "相对路径,如 notes/2024/01/15.md"
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
#### `molymemos.status`
|
|
77
|
+
|
|
78
|
+
获取插件状态。
|
|
79
|
+
|
|
80
|
+
响应:
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"serverUrl": "ws://localhost:8080",
|
|
84
|
+
"connected": true,
|
|
85
|
+
"workspaceDir": "~/.openclaw/workspace",
|
|
86
|
+
"molyMemosDir": "~/.openclaw/workspace/memory/molymemos"
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### HTTP 路由
|
|
91
|
+
|
|
92
|
+
#### `POST /molymemos/append`
|
|
93
|
+
|
|
94
|
+
手动追加内容到文件。
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -X POST http://localhost:port/molymemos/append \
|
|
98
|
+
-H "Content-Type: application/json" \
|
|
99
|
+
-d '{"content": "Hello World", "filepath": "test.md"}'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
#### `GET /molymemos/status`
|
|
103
|
+
|
|
104
|
+
获取插件状态。
|
|
105
|
+
|
|
106
|
+
### Agent 工具
|
|
107
|
+
|
|
108
|
+
#### `append_memo`
|
|
109
|
+
|
|
110
|
+
Agent 可调用的工具,用于追加内容到记忆文件夹。
|
|
111
|
+
|
|
112
|
+
参数:
|
|
113
|
+
- `content`: 要追加的内容
|
|
114
|
+
- `filepath`: 相对文件路径
|
|
115
|
+
|
|
116
|
+
## 文件结构
|
|
117
|
+
|
|
118
|
+
内容会被追加到 `{workspaceDir}/memory/molymemos/{filepath}` 路径下。
|
|
119
|
+
|
|
120
|
+
例如,如果 `workspaceDir` 是 `~/.openclaw/workspace`,`filepath` 是 `notes/daily.md`,
|
|
121
|
+
那么内容会追加到 `~/.openclaw/workspace/memory/molymemos/notes/daily.md`。
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
3
|
+
declare const molyMemosPlugin: {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
configSchema: z.ZodObject<{
|
|
8
|
+
serverUrl: z.ZodString;
|
|
9
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
10
|
+
reconnectInterval: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
serverUrl: string;
|
|
13
|
+
apiKey?: string | undefined;
|
|
14
|
+
reconnectInterval?: number | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
serverUrl: string;
|
|
17
|
+
apiKey?: string | undefined;
|
|
18
|
+
reconnectInterval?: number | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
register(api: OpenClawPluginApi): void;
|
|
21
|
+
};
|
|
22
|
+
export default molyMemosPlugin;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAW7D,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;kBAML,iBAAiB;CAyHhC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { MolyMemosServerClient } from "./server-client.js";
|
|
5
|
+
const configSchema = z.object({
|
|
6
|
+
serverUrl: z.string(),
|
|
7
|
+
apiKey: z.string().optional(),
|
|
8
|
+
reconnectInterval: z.number().optional(),
|
|
9
|
+
});
|
|
10
|
+
const molyMemosPlugin = {
|
|
11
|
+
id: "molymemos",
|
|
12
|
+
name: "MolyMemos",
|
|
13
|
+
description: "Receive content from server via WebSocket and append to memory folder",
|
|
14
|
+
configSchema,
|
|
15
|
+
register(api) {
|
|
16
|
+
const config = configSchema.parse(api.pluginConfig);
|
|
17
|
+
const logger = api.logger;
|
|
18
|
+
const serverClient = new MolyMemosServerClient({
|
|
19
|
+
serverUrl: config.serverUrl,
|
|
20
|
+
apiKey: config.apiKey,
|
|
21
|
+
reconnectInterval: config.reconnectInterval,
|
|
22
|
+
});
|
|
23
|
+
serverClient.setLogger(logger);
|
|
24
|
+
const resolveWorkspaceDir = () => {
|
|
25
|
+
const stateDir = api.runtime.state.resolveStateDir();
|
|
26
|
+
return path.join(stateDir, "workspace");
|
|
27
|
+
};
|
|
28
|
+
const getMolyMemosPath = (filepath) => {
|
|
29
|
+
const wsDir = resolveWorkspaceDir();
|
|
30
|
+
return path.join(wsDir, "memory", "molymemos", filepath);
|
|
31
|
+
};
|
|
32
|
+
const ensureDirectoryExists = (filePath) => {
|
|
33
|
+
const dir = path.dirname(filePath);
|
|
34
|
+
if (!fs.existsSync(dir)) {
|
|
35
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const appendToFile = (content, filepath) => {
|
|
39
|
+
const fullPath = getMolyMemosPath(filepath);
|
|
40
|
+
ensureDirectoryExists(fullPath);
|
|
41
|
+
try {
|
|
42
|
+
fs.appendFileSync(fullPath, content + "\n", "utf-8");
|
|
43
|
+
logger.info(`Content appended to ${fullPath}`);
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
message: `Content successfully appended to ${filepath}`,
|
|
47
|
+
fullPath,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
52
|
+
logger.error(`Failed to append content to ${fullPath}: ${errorMessage}`);
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
message: `Failed to append content: ${errorMessage}`,
|
|
56
|
+
fullPath,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const handleServerMessage = async (message) => {
|
|
61
|
+
const result = appendToFile(message.content, message.filepath);
|
|
62
|
+
if (!result.success) {
|
|
63
|
+
logger.error(`Failed to handle server message: ${result.message}`);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
serverClient.setMessageHandler(handleServerMessage);
|
|
67
|
+
api.registerGatewayMethod("molymemos.append", async ({ params, respond }) => {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = z.object({
|
|
70
|
+
content: z.string(),
|
|
71
|
+
filepath: z.string(),
|
|
72
|
+
}).parse(params);
|
|
73
|
+
const result = appendToFile(parsed.content, parsed.filepath);
|
|
74
|
+
if (result.success) {
|
|
75
|
+
respond(true, result);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
respond(false, { error: result.message });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
83
|
+
logger.error(`molymemos.append error: ${errorMessage}`);
|
|
84
|
+
respond(false, { error: errorMessage });
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
api.registerGatewayMethod("molymemos.status", async ({ respond }) => {
|
|
88
|
+
const wsDir = resolveWorkspaceDir();
|
|
89
|
+
respond(true, {
|
|
90
|
+
serverUrl: config.serverUrl,
|
|
91
|
+
connected: serverClient.isConnected(),
|
|
92
|
+
workspaceDir: wsDir,
|
|
93
|
+
molyMemosDir: path.join(wsDir, "memory", "molymemos"),
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
api.registerService({
|
|
97
|
+
id: "molymemos",
|
|
98
|
+
start: async () => {
|
|
99
|
+
logger.info("MolyMemos service starting...");
|
|
100
|
+
logger.info(`Connecting to server: ${config.serverUrl}`);
|
|
101
|
+
const connected = await serverClient.connect();
|
|
102
|
+
if (connected) {
|
|
103
|
+
logger.info("Connected to MolyMemos server");
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
logger.warn("Failed to connect to server, will retry...");
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
stop: async () => {
|
|
110
|
+
logger.info("MolyMemos service stopping...");
|
|
111
|
+
await serverClient.disconnect();
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
const defaultWsDir = resolveWorkspaceDir();
|
|
115
|
+
logger.info(`MolyMemos plugin registered, molymemos path: ${path.join(defaultWsDir, "memory", "molymemos")}`);
|
|
116
|
+
logger.info(`Server URL: ${config.serverUrl}`);
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
export default molyMemosPlugin;
|
|
120
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "molymemos",
|
|
3
|
+
"name": "MolyMemos",
|
|
4
|
+
"description": "Receive content from server via WebSocket and append to memory folder",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"configSchema": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"serverUrl": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "WebSocket server URL to connect to (e.g. ws://localhost:8080 or wss://example.com)"
|
|
13
|
+
},
|
|
14
|
+
"apiKey": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "API key for authentication"
|
|
17
|
+
},
|
|
18
|
+
"reconnectInterval": {
|
|
19
|
+
"type": "number",
|
|
20
|
+
"description": "Reconnect interval in milliseconds",
|
|
21
|
+
"default": 5000
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": ["serverUrl"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export interface PluginLogger {
|
|
3
|
+
debug?: (message: string) => void;
|
|
4
|
+
info: (message: string) => void;
|
|
5
|
+
warn: (message: string) => void;
|
|
6
|
+
error: (message: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface ServerConfig {
|
|
9
|
+
serverUrl: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
reconnectInterval?: number;
|
|
12
|
+
}
|
|
13
|
+
declare const memoMessageSchema: z.ZodObject<{
|
|
14
|
+
type: z.ZodLiteral<"memo">;
|
|
15
|
+
content: z.ZodString;
|
|
16
|
+
filepath: z.ZodString;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
type: "memo";
|
|
19
|
+
content: string;
|
|
20
|
+
filepath: string;
|
|
21
|
+
}, {
|
|
22
|
+
type: "memo";
|
|
23
|
+
content: string;
|
|
24
|
+
filepath: string;
|
|
25
|
+
}>;
|
|
26
|
+
export type MemoMessage = z.infer<typeof memoMessageSchema>;
|
|
27
|
+
export type MessageHandler = (message: MemoMessage) => Promise<void>;
|
|
28
|
+
export declare class MolyMemosServerClient {
|
|
29
|
+
private serverUrl;
|
|
30
|
+
private apiKey?;
|
|
31
|
+
private reconnectInterval;
|
|
32
|
+
private ws;
|
|
33
|
+
private connected;
|
|
34
|
+
private shouldReconnect;
|
|
35
|
+
private reconnectTimer;
|
|
36
|
+
private messageHandler;
|
|
37
|
+
private logger;
|
|
38
|
+
constructor(config: ServerConfig);
|
|
39
|
+
setLogger(logger: PluginLogger): void;
|
|
40
|
+
setMessageHandler(handler: MessageHandler): void;
|
|
41
|
+
connect(): Promise<boolean>;
|
|
42
|
+
private doConnect;
|
|
43
|
+
private handleMessage;
|
|
44
|
+
private scheduleReconnect;
|
|
45
|
+
disconnect(): Promise<void>;
|
|
46
|
+
isConnected(): boolean;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=server-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-client.d.ts","sourceRoot":"","sources":["../src/server-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,QAAA,MAAM,iBAAiB;;;;;;;;;;;;EAIrB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,MAAM,CAA6B;gBAE/B,MAAM,EAAE,YAAY;IAMhC,SAAS,CAAC,MAAM,EAAE,YAAY;IAI9B,iBAAiB,CAAC,OAAO,EAAE,cAAc;IAInC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IASjC,OAAO,CAAC,SAAS;IA4CjB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,iBAAiB;IAiBnB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC,WAAW,IAAI,OAAO;CAGvB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import WebSocket from "ws";
|
|
3
|
+
const memoMessageSchema = z.object({
|
|
4
|
+
type: z.literal("memo"),
|
|
5
|
+
content: z.string(),
|
|
6
|
+
filepath: z.string(),
|
|
7
|
+
});
|
|
8
|
+
export class MolyMemosServerClient {
|
|
9
|
+
serverUrl;
|
|
10
|
+
apiKey;
|
|
11
|
+
reconnectInterval;
|
|
12
|
+
ws = null;
|
|
13
|
+
connected = false;
|
|
14
|
+
shouldReconnect = false;
|
|
15
|
+
reconnectTimer = null;
|
|
16
|
+
messageHandler = null;
|
|
17
|
+
logger = null;
|
|
18
|
+
constructor(config) {
|
|
19
|
+
this.serverUrl = config.serverUrl.replace(/^http/, "ws").replace(/\/$/, "");
|
|
20
|
+
this.apiKey = config.apiKey;
|
|
21
|
+
this.reconnectInterval = config.reconnectInterval ?? 5000;
|
|
22
|
+
}
|
|
23
|
+
setLogger(logger) {
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
}
|
|
26
|
+
setMessageHandler(handler) {
|
|
27
|
+
this.messageHandler = handler;
|
|
28
|
+
}
|
|
29
|
+
async connect() {
|
|
30
|
+
if (this.ws && this.connected) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
this.shouldReconnect = true;
|
|
34
|
+
return this.doConnect();
|
|
35
|
+
}
|
|
36
|
+
doConnect() {
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
if (!this.shouldReconnect) {
|
|
39
|
+
resolve(false);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const url = this.apiKey
|
|
44
|
+
? `${this.serverUrl}/ws?token=${encodeURIComponent(this.apiKey)}`
|
|
45
|
+
: `${this.serverUrl}/ws`;
|
|
46
|
+
this.logger?.info(`Connecting to WebSocket: ${this.serverUrl}/ws`);
|
|
47
|
+
this.ws = new WebSocket(url);
|
|
48
|
+
this.ws.on("open", () => {
|
|
49
|
+
this.connected = true;
|
|
50
|
+
this.logger?.info("WebSocket connected");
|
|
51
|
+
resolve(true);
|
|
52
|
+
});
|
|
53
|
+
this.ws.on("message", (data) => {
|
|
54
|
+
this.handleMessage(data);
|
|
55
|
+
});
|
|
56
|
+
this.ws.on("close", (code, reason) => {
|
|
57
|
+
this.connected = false;
|
|
58
|
+
this.logger?.info(`WebSocket closed: ${code} ${reason?.toString() || ""}`);
|
|
59
|
+
this.scheduleReconnect();
|
|
60
|
+
});
|
|
61
|
+
this.ws.on("error", (err) => {
|
|
62
|
+
this.logger?.error(`WebSocket error: ${err.message}`);
|
|
63
|
+
this.connected = false;
|
|
64
|
+
resolve(false);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
this.logger?.error(`Failed to create WebSocket: ${error}`);
|
|
69
|
+
this.connected = false;
|
|
70
|
+
resolve(false);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
handleMessage(data) {
|
|
75
|
+
try {
|
|
76
|
+
const raw = typeof data === "string" ? data : data.toString();
|
|
77
|
+
const json = JSON.parse(raw);
|
|
78
|
+
const parsed = memoMessageSchema.safeParse(json);
|
|
79
|
+
if (parsed.success && this.messageHandler) {
|
|
80
|
+
this.logger?.debug?.(`Received memo: ${parsed.data.filepath}`);
|
|
81
|
+
this.messageHandler(parsed.data).catch((err) => {
|
|
82
|
+
this.logger?.error(`Error handling message: ${err}`);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else if (!parsed.success) {
|
|
86
|
+
this.logger?.debug?.(`Ignored message: ${raw.slice(0, 100)}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.logger?.error(`Failed to parse message: ${error}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
scheduleReconnect() {
|
|
94
|
+
if (!this.shouldReconnect) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (this.reconnectTimer) {
|
|
98
|
+
clearTimeout(this.reconnectTimer);
|
|
99
|
+
}
|
|
100
|
+
this.logger?.info(`Reconnecting in ${this.reconnectInterval}ms...`);
|
|
101
|
+
this.reconnectTimer = setTimeout(() => {
|
|
102
|
+
if (this.shouldReconnect) {
|
|
103
|
+
this.doConnect().catch(() => { });
|
|
104
|
+
}
|
|
105
|
+
}, this.reconnectInterval);
|
|
106
|
+
}
|
|
107
|
+
async disconnect() {
|
|
108
|
+
this.shouldReconnect = false;
|
|
109
|
+
if (this.reconnectTimer) {
|
|
110
|
+
clearTimeout(this.reconnectTimer);
|
|
111
|
+
this.reconnectTimer = null;
|
|
112
|
+
}
|
|
113
|
+
if (this.ws) {
|
|
114
|
+
this.ws.close();
|
|
115
|
+
this.ws = null;
|
|
116
|
+
}
|
|
117
|
+
this.connected = false;
|
|
118
|
+
this.logger?.info("WebSocket disconnected");
|
|
119
|
+
}
|
|
120
|
+
isConnected() {
|
|
121
|
+
return this.connected;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=server-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-client.js","sourceRoot":"","sources":["../src/server-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,SAAS,MAAM,IAAI,CAAC;AAe3B,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC;AAMH,MAAM,OAAO,qBAAqB;IACxB,SAAS,CAAS;IAClB,MAAM,CAAU;IAChB,iBAAiB,CAAS;IAC1B,EAAE,GAAqB,IAAI,CAAC;IAC5B,SAAS,GAAY,KAAK,CAAC;IAC3B,eAAe,GAAY,KAAK,CAAC;IACjC,cAAc,GAAyC,IAAI,CAAC;IAC5D,cAAc,GAA0B,IAAI,CAAC;IAC7C,MAAM,GAAwB,IAAI,CAAC;IAE3C,YAAY,MAAoB;QAC9B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,IAAI,CAAC;IAC5D,CAAC;IAED,SAAS,CAAC,MAAoB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,iBAAiB,CAAC,OAAuB;QACvC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;IAEO,SAAS;QACf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1B,OAAO,CAAC,KAAK,CAAC,CAAC;gBACf,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM;oBACrB,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;oBACjE,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,KAAK,CAAC;gBAE3B,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,4BAA4B,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC;gBACnE,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;gBAE7B,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;oBACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;oBACtB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,CAAC,CAAC;oBACzC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAoB,EAAE,EAAE;oBAC7C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;oBACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACvB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,IAAI,IAAI,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC3E,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;oBAC1B,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,oBAAoB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;oBACtD,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;oBACvB,OAAO,CAAC,KAAK,CAAC,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;gBAC3D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,IAAoB;QACxC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;YACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAEjD,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC1C,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,kBAAkB,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC7C,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;gBACvD,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,oBAAoB,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,mBAAmB,IAAI,CAAC,iBAAiB,OAAO,CAAC,CAAC;QACpE,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAE7B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openclaw-molymemos",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenClaw plugin for MolyMemos - append content to memory folder",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc && cp openclaw.plugin.json dist/",
|
|
10
|
+
"dev": "tsc --watch",
|
|
11
|
+
"clean": "rm -rf dist",
|
|
12
|
+
"prepublishOnly": "npm run build"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"openclaw",
|
|
19
|
+
"plugin",
|
|
20
|
+
"molymemos",
|
|
21
|
+
"memory"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"ws": "^8.16.0",
|
|
25
|
+
"zod": "^3.22.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^20.10.0",
|
|
29
|
+
"@types/ws": "^8.5.10",
|
|
30
|
+
"typescript": "^5.3.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"openclaw": "*"
|
|
34
|
+
}
|
|
35
|
+
}
|