@mind2flow/daemon 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.
Files changed (41) hide show
  1. package/dist/command-center-client.d.ts +32 -0
  2. package/dist/command-center-client.d.ts.map +1 -0
  3. package/dist/command-center-client.js +137 -0
  4. package/dist/command-center-client.js.map +1 -0
  5. package/dist/config.d.ts +51 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +89 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/daemon.d.ts +21 -0
  10. package/dist/daemon.d.ts.map +1 -0
  11. package/dist/daemon.js +1937 -0
  12. package/dist/daemon.js.map +1 -0
  13. package/dist/gateway-client.d.ts +175 -0
  14. package/dist/gateway-client.d.ts.map +1 -0
  15. package/dist/gateway-client.js +494 -0
  16. package/dist/gateway-client.js.map +1 -0
  17. package/dist/heartbeat.d.ts +35 -0
  18. package/dist/heartbeat.d.ts.map +1 -0
  19. package/dist/heartbeat.js +116 -0
  20. package/dist/heartbeat.js.map +1 -0
  21. package/dist/openclaw-manager.d.ts +41 -0
  22. package/dist/openclaw-manager.d.ts.map +1 -0
  23. package/dist/openclaw-manager.js +199 -0
  24. package/dist/openclaw-manager.js.map +1 -0
  25. package/dist/protocols/index.d.ts +21 -0
  26. package/dist/protocols/index.d.ts.map +1 -0
  27. package/dist/protocols/index.js +30 -0
  28. package/dist/protocols/index.js.map +1 -0
  29. package/dist/protocols/jsonrpc-protocol.d.ts +24 -0
  30. package/dist/protocols/jsonrpc-protocol.d.ts.map +1 -0
  31. package/dist/protocols/jsonrpc-protocol.js +83 -0
  32. package/dist/protocols/jsonrpc-protocol.js.map +1 -0
  33. package/dist/protocols/openclaw-protocol.d.ts +33 -0
  34. package/dist/protocols/openclaw-protocol.d.ts.map +1 -0
  35. package/dist/protocols/openclaw-protocol.js +131 -0
  36. package/dist/protocols/openclaw-protocol.js.map +1 -0
  37. package/dist/protocols/types.d.ts +86 -0
  38. package/dist/protocols/types.d.ts.map +1 -0
  39. package/dist/protocols/types.js +13 -0
  40. package/dist/protocols/types.js.map +1 -0
  41. package/package.json +40 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Heartbeat sender — collects system information and sends periodic
3
+ * heartbeats to the Command Center.
4
+ */
5
+ import { hostname, platform, release, arch, cpus, totalmem, freemem } from "node:os";
6
+ // ── CPU usage tracker ────────────────────────────────────────────
7
+ let lastCpuTimes = null;
8
+ function getCpuUsage() {
9
+ const cores = cpus();
10
+ let idle = 0;
11
+ let total = 0;
12
+ for (const core of cores) {
13
+ idle += core.times.idle;
14
+ total += core.times.user + core.times.nice + core.times.sys + core.times.irq + core.times.idle;
15
+ }
16
+ if (!lastCpuTimes) {
17
+ lastCpuTimes = { idle, total };
18
+ return 0; // First call — no delta available
19
+ }
20
+ const idleDelta = idle - lastCpuTimes.idle;
21
+ const totalDelta = total - lastCpuTimes.total;
22
+ lastCpuTimes = { idle, total };
23
+ if (totalDelta === 0)
24
+ return 0;
25
+ return Math.round(((totalDelta - idleDelta) / totalDelta) * 100);
26
+ }
27
+ // ── System info collector ────────────────────────────────────────
28
+ function collectSystemInfo() {
29
+ const coreList = cpus();
30
+ return {
31
+ hostname: hostname(),
32
+ os_type: platform(),
33
+ os_version: release(),
34
+ arch: arch(),
35
+ cpu_count: coreList.length,
36
+ cpu_model: coreList[0]?.model ?? "unknown",
37
+ total_memory_mb: Math.round(totalmem() / 1024 / 1024),
38
+ free_memory_mb: Math.round(freemem() / 1024 / 1024),
39
+ cpu_usage_percent: getCpuUsage(),
40
+ uptime_seconds: Math.round(process.uptime()),
41
+ };
42
+ }
43
+ // ── Heartbeat service ────────────────────────────────────────────
44
+ export class HeartbeatService {
45
+ client;
46
+ gateway;
47
+ manager;
48
+ intervalMs;
49
+ timer = null;
50
+ logLevel;
51
+ constructor(client, gateway, manager, intervalMs, logLevel = "info") {
52
+ this.client = client;
53
+ this.gateway = gateway;
54
+ this.manager = manager;
55
+ this.intervalMs = intervalMs;
56
+ this.logLevel = logLevel;
57
+ }
58
+ start() {
59
+ if (this.timer)
60
+ return;
61
+ this.log("info", `Heartbeat started (every ${this.intervalMs / 1000}s)`);
62
+ // Send immediately, then on interval
63
+ this.send();
64
+ this.timer = setInterval(() => this.send(), this.intervalMs);
65
+ }
66
+ stop() {
67
+ if (this.timer) {
68
+ clearInterval(this.timer);
69
+ this.timer = null;
70
+ this.log("info", "Heartbeat stopped");
71
+ }
72
+ }
73
+ send() {
74
+ if (!this.client.isConnected)
75
+ return;
76
+ const sysInfo = collectSystemInfo();
77
+ const gatewayConnected = this.gateway.isConnected;
78
+ const gatewayRunning = this.manager.isRunning;
79
+ let status = "online";
80
+ if (!gatewayRunning)
81
+ status = "error";
82
+ else if (!gatewayConnected)
83
+ status = "busy"; // gateway running but RPC not connected yet
84
+ this.client.send({
85
+ type: "heartbeat",
86
+ status,
87
+ meta: {
88
+ ...sysInfo,
89
+ gateway_running: gatewayRunning,
90
+ gateway_connected: gatewayConnected,
91
+ gateway_pid: this.manager.pid,
92
+ },
93
+ });
94
+ this.log("debug", `Heartbeat sent: status=${status} cpu=${sysInfo.cpu_usage_percent}%`);
95
+ }
96
+ /** Send one-time system info (used after initial connection). */
97
+ sendSystemInfo() {
98
+ const info = collectSystemInfo();
99
+ this.client.send({
100
+ type: "status_update",
101
+ status: "online",
102
+ user_id: "", // filled by server from instance record
103
+ system_info: info,
104
+ });
105
+ }
106
+ // ── Logging ────────────────────────────────────────────────────
107
+ log(level, msg) {
108
+ const levels = ["debug", "info", "warn", "error"];
109
+ if (levels.indexOf(level) >= levels.indexOf(this.logLevel)) {
110
+ const ts = new Date().toISOString();
111
+ const prefix = `[${ts}] [Heartbeat] [${level.toUpperCase()}]`;
112
+ console.log(`${prefix} ${msg}`);
113
+ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * OpenClaw process manager — start, stop, and monitor the local
3
+ * OpenClaw Gateway subprocess.
4
+ *
5
+ * Handles:
6
+ * - Locating the openclaw binary
7
+ * - Starting the Gateway process (openclaw gateway --port <port>)
8
+ * - Setting environment variables for LLM API keys
9
+ * - Monitoring the process (restart on crash)
10
+ * - Graceful shutdown
11
+ */
12
+ import { EventEmitter } from "node:events";
13
+ import type { LLMConfig } from "./config.js";
14
+ interface ManagerOptions {
15
+ port: number;
16
+ openclawBin: string | null;
17
+ logLevel: string;
18
+ }
19
+ export declare class OpenClawManager extends EventEmitter {
20
+ private process;
21
+ private port;
22
+ private binPath;
23
+ private logLevel;
24
+ private shouldRestart;
25
+ private restartDelay;
26
+ private restartTimer;
27
+ private envOverrides;
28
+ constructor(options: ManagerOptions);
29
+ /** Binary names to search for, in priority order. */
30
+ private static readonly BIN_NAMES;
31
+ private resolveBin;
32
+ applyLLMConfig(config: LLMConfig): void;
33
+ start(): Promise<void>;
34
+ stop(): Promise<void>;
35
+ restart(): Promise<void>;
36
+ get isRunning(): boolean;
37
+ get pid(): number | null;
38
+ private log;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=openclaw-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-manager.d.ts","sourceRoot":"","sources":["../src/openclaw-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkBD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,YAAY,CAA8B;gBAEtC,OAAO,EAAE,cAAc;IASnC,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAEzE,OAAO,CAAC,UAAU;IA0BlB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAuBjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoEtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,GAAG,IAAI,MAAM,GAAG,IAAI,CAEvB;IAID,OAAO,CAAC,GAAG;CAUZ"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * OpenClaw process manager — start, stop, and monitor the local
3
+ * OpenClaw Gateway subprocess.
4
+ *
5
+ * Handles:
6
+ * - Locating the openclaw binary
7
+ * - Starting the Gateway process (openclaw gateway --port <port>)
8
+ * - Setting environment variables for LLM API keys
9
+ * - Monitoring the process (restart on crash)
10
+ * - Graceful shutdown
11
+ */
12
+ import { spawn, execSync } from "node:child_process";
13
+ import { existsSync } from "node:fs";
14
+ import { EventEmitter } from "node:events";
15
+ // ── LLM Provider → Env var mapping ────────────────────────────────
16
+ const PROVIDER_ENV_MAP = {
17
+ openai: "OPENAI_API_KEY",
18
+ anthropic: "ANTHROPIC_API_KEY",
19
+ groq: "GROQ_API_KEY",
20
+ google: "GOOGLE_API_KEY",
21
+ mistral: "MISTRAL_API_KEY",
22
+ cohere: "COHERE_API_KEY",
23
+ together: "TOGETHER_API_KEY",
24
+ fireworks: "FIREWORKS_API_KEY",
25
+ openrouter: "OPENROUTER_API_KEY",
26
+ };
27
+ // ── Manager ────────────────────────────────────────────────────────
28
+ export class OpenClawManager extends EventEmitter {
29
+ process = null;
30
+ port;
31
+ binPath;
32
+ logLevel;
33
+ shouldRestart = true;
34
+ restartDelay = 3_000;
35
+ restartTimer = null;
36
+ envOverrides = {};
37
+ constructor(options) {
38
+ super();
39
+ this.port = options.port;
40
+ this.binPath = options.openclawBin;
41
+ this.logLevel = options.logLevel;
42
+ }
43
+ // ── Binary resolution ──────────────────────────────────────────
44
+ /** Binary names to search for, in priority order. */
45
+ static BIN_NAMES = ["clawdbot", "openclaw", "m2f-claw"];
46
+ resolveBin() {
47
+ if (this.binPath && existsSync(this.binPath)) {
48
+ return this.binPath;
49
+ }
50
+ // Try to find via `which` (Unix) or `where` (Windows)
51
+ const whichCmd = process.platform === "win32" ? "where" : "which";
52
+ for (const name of OpenClawManager.BIN_NAMES) {
53
+ try {
54
+ const result = execSync(`${whichCmd} ${name}`, { encoding: "utf-8" }).trim();
55
+ if (result) {
56
+ this.log("info", `Found gateway binary at: ${result}`);
57
+ return result.split("\n")[0]; // first match
58
+ }
59
+ }
60
+ catch {
61
+ // not found — try next
62
+ }
63
+ }
64
+ // Try npx fallback with the correct npm package name
65
+ this.log("warn", "Gateway binary not found in PATH — will try npx @mind2flow/claw");
66
+ return "npx";
67
+ }
68
+ // ── LLM env var management ─────────────────────────────────────
69
+ applyLLMConfig(config) {
70
+ // Clear previous provider env vars
71
+ for (const envVar of Object.values(PROVIDER_ENV_MAP)) {
72
+ delete this.envOverrides[envVar];
73
+ }
74
+ // Set the new provider's key
75
+ const envVar = PROVIDER_ENV_MAP[config.provider.toLowerCase()];
76
+ if (envVar && config.apiKey) {
77
+ this.envOverrides[envVar] = config.apiKey;
78
+ this.log("info", `Set ${envVar} for provider ${config.provider}`);
79
+ }
80
+ // For custom base URLs
81
+ if (config.baseUrl) {
82
+ this.envOverrides["OPENAI_BASE_URL"] = config.baseUrl;
83
+ }
84
+ this.emit("llm-config-applied", config);
85
+ }
86
+ // ── Start ──────────────────────────────────────────────────────
87
+ async start() {
88
+ if (this.process) {
89
+ this.log("warn", "Gateway already running");
90
+ return;
91
+ }
92
+ this.shouldRestart = true;
93
+ const bin = this.resolveBin();
94
+ // --allow-unconfigured: skip config gate if ~/.clawdbot/clawdbot.json is missing
95
+ // --force: skip port-in-use check (daemon manages lifecycle)
96
+ // --bind loopback: only listen on 127.0.0.1 for security
97
+ const args = bin === "npx"
98
+ ? ["@mind2flow/claw", "gateway", "--port", String(this.port), "--bind", "loopback", "--allow-unconfigured", "--force"]
99
+ : ["gateway", "--port", String(this.port), "--bind", "loopback", "--allow-unconfigured", "--force"];
100
+ this.log("info", `Starting OpenClaw Gateway: ${bin} ${args.join(" ")}`);
101
+ const env = {
102
+ ...process.env,
103
+ ...this.envOverrides,
104
+ };
105
+ this.process = spawn(bin, args, {
106
+ env,
107
+ stdio: ["ignore", "pipe", "pipe"],
108
+ detached: false,
109
+ });
110
+ this.process.stdout?.on("data", (data) => {
111
+ const line = data.toString().trim();
112
+ if (line)
113
+ this.log("debug", `[gateway] ${line}`);
114
+ });
115
+ this.process.stderr?.on("data", (data) => {
116
+ const line = data.toString().trim();
117
+ if (line)
118
+ this.log("warn", `[gateway:err] ${line}`);
119
+ });
120
+ this.process.on("exit", (code, signal) => {
121
+ this.log("info", `Gateway exited (code=${code} signal=${signal})`);
122
+ this.process = null;
123
+ this.emit("exited", { code, signal });
124
+ if (this.shouldRestart && code !== 0) {
125
+ this.log("info", `Restarting Gateway in ${this.restartDelay / 1000}s…`);
126
+ this.restartTimer = setTimeout(() => {
127
+ this.restartTimer = null;
128
+ this.start();
129
+ }, this.restartDelay);
130
+ }
131
+ });
132
+ this.process.on("error", (err) => {
133
+ this.log("error", `Failed to start Gateway: ${err.message}`);
134
+ this.process = null;
135
+ this.emit("error", err);
136
+ });
137
+ // Wait briefly for startup
138
+ await new Promise((resolve) => setTimeout(resolve, 2_000));
139
+ if (this.process) {
140
+ this.emit("started");
141
+ }
142
+ }
143
+ // ── Stop ───────────────────────────────────────────────────────
144
+ async stop() {
145
+ this.shouldRestart = false;
146
+ if (this.restartTimer) {
147
+ clearTimeout(this.restartTimer);
148
+ this.restartTimer = null;
149
+ }
150
+ if (!this.process)
151
+ return;
152
+ this.log("info", "Stopping OpenClaw Gateway…");
153
+ return new Promise((resolve) => {
154
+ const forceKill = setTimeout(() => {
155
+ if (this.process) {
156
+ this.log("warn", "Force-killing Gateway");
157
+ this.process.kill("SIGKILL");
158
+ }
159
+ resolve();
160
+ }, 5_000);
161
+ this.process.once("exit", () => {
162
+ clearTimeout(forceKill);
163
+ this.process = null;
164
+ resolve();
165
+ });
166
+ // Graceful signal
167
+ this.process.kill("SIGTERM");
168
+ });
169
+ }
170
+ // ── Restart (for config changes) ───────────────────────────────
171
+ async restart() {
172
+ this.log("info", "Restarting Gateway for config change…");
173
+ await this.stop();
174
+ this.shouldRestart = true;
175
+ await this.start();
176
+ }
177
+ // ── State ──────────────────────────────────────────────────────
178
+ get isRunning() {
179
+ return this.process !== null && !this.process.killed;
180
+ }
181
+ get pid() {
182
+ return this.process?.pid ?? null;
183
+ }
184
+ // ── Logging ────────────────────────────────────────────────────
185
+ log(level, msg) {
186
+ const levels = ["debug", "info", "warn", "error"];
187
+ if (levels.indexOf(level) >= levels.indexOf(this.logLevel)) {
188
+ const ts = new Date().toISOString();
189
+ const prefix = `[${ts}] [OC-Manager] [${level.toUpperCase()}]`;
190
+ if (level === "error")
191
+ console.error(`${prefix} ${msg}`);
192
+ else if (level === "warn")
193
+ console.warn(`${prefix} ${msg}`);
194
+ else
195
+ console.log(`${prefix} ${msg}`);
196
+ }
197
+ }
198
+ }
199
+ //# sourceMappingURL=openclaw-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-manager.js","sourceRoot":"","sources":["../src/openclaw-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Protocol adapters barrel export + factory.
3
+ *
4
+ * Usage:
5
+ * import { createProtocol } from "./protocols/index.js";
6
+ * const protocol = createProtocol("openclaw");
7
+ */
8
+ export type { ProtocolAdapter, GatewayRequest, GatewayResponse, GatewayEvent, ParsedMessage, HandshakeOptions } from "./types.js";
9
+ export { type ProtocolType } from "./types.js";
10
+ export { OpenClawProtocol } from "./openclaw-protocol.js";
11
+ export { JsonRpcProtocol } from "./jsonrpc-protocol.js";
12
+ import type { ProtocolAdapter } from "./types.js";
13
+ import type { ProtocolType } from "./types.js";
14
+ /**
15
+ * Factory — create a protocol adapter by name.
16
+ *
17
+ * @param type - "openclaw" for the native OpenClaw wire format,
18
+ * "jsonrpc" for standard JSON-RPC 2.0
19
+ */
20
+ export declare function createProtocol(type: ProtocolType): ProtocolAdapter;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/protocols/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAClI,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,CAWlE"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Protocol adapters barrel export + factory.
3
+ *
4
+ * Usage:
5
+ * import { createProtocol } from "./protocols/index.js";
6
+ * const protocol = createProtocol("openclaw");
7
+ */
8
+ export { OpenClawProtocol } from "./openclaw-protocol.js";
9
+ export { JsonRpcProtocol } from "./jsonrpc-protocol.js";
10
+ import { OpenClawProtocol } from "./openclaw-protocol.js";
11
+ import { JsonRpcProtocol } from "./jsonrpc-protocol.js";
12
+ /**
13
+ * Factory — create a protocol adapter by name.
14
+ *
15
+ * @param type - "openclaw" for the native OpenClaw wire format,
16
+ * "jsonrpc" for standard JSON-RPC 2.0
17
+ */
18
+ export function createProtocol(type) {
19
+ switch (type) {
20
+ case "openclaw":
21
+ return new OpenClawProtocol();
22
+ case "jsonrpc":
23
+ return new JsonRpcProtocol();
24
+ default: {
25
+ const exhaustive = type;
26
+ throw new Error(`Unknown protocol type: ${exhaustive}`);
27
+ }
28
+ }
29
+ }
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protocols/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAkB;IAC/C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,UAAU;YACb,OAAO,IAAI,gBAAgB,EAAE,CAAC;QAChC,KAAK,SAAS;YACZ,OAAO,IAAI,eAAe,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,IAAI,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Standard JSON-RPC 2.0 protocol adapter.
3
+ *
4
+ * For gateways that implement the JSON-RPC 2.0 specification:
5
+ * https://www.jsonrpc.org/specification
6
+ *
7
+ * Wire format:
8
+ * Request: { jsonrpc: "2.0", id: string, method: string, params?: object }
9
+ * Response: { jsonrpc: "2.0", id: string, result?: unknown } (success)
10
+ * { jsonrpc: "2.0", id: string, error: { code, message, data? } } (error)
11
+ * Notification: { jsonrpc: "2.0", method: string, params?: object } (no id)
12
+ *
13
+ * No handshake required — client can send requests immediately after
14
+ * WebSocket connection is open.
15
+ */
16
+ import type { ProtocolAdapter, GatewayRequest, ParsedMessage, HandshakeOptions } from "./types.js";
17
+ export declare class JsonRpcProtocol implements ProtocolAdapter {
18
+ readonly name = "jsonrpc";
19
+ buildHandshake(_opts: HandshakeOptions): string | null;
20
+ encodeRequest(req: GatewayRequest): string;
21
+ parseMessage(raw: string): ParsedMessage;
22
+ isHandshakeResponse(_raw: string): boolean | null;
23
+ }
24
+ //# sourceMappingURL=jsonrpc-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonrpc-protocol.d.ts","sourceRoot":"","sources":["../../src/protocols/jsonrpc-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AA8BpB,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,aAAa;IAE1B,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI;IAKtD,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAY1C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IAkDxC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;CAIlD"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Standard JSON-RPC 2.0 protocol adapter.
3
+ *
4
+ * For gateways that implement the JSON-RPC 2.0 specification:
5
+ * https://www.jsonrpc.org/specification
6
+ *
7
+ * Wire format:
8
+ * Request: { jsonrpc: "2.0", id: string, method: string, params?: object }
9
+ * Response: { jsonrpc: "2.0", id: string, result?: unknown } (success)
10
+ * { jsonrpc: "2.0", id: string, error: { code, message, data? } } (error)
11
+ * Notification: { jsonrpc: "2.0", method: string, params?: object } (no id)
12
+ *
13
+ * No handshake required — client can send requests immediately after
14
+ * WebSocket connection is open.
15
+ */
16
+ // ── Adapter implementation ─────────────────────────────────────
17
+ export class JsonRpcProtocol {
18
+ name = "jsonrpc";
19
+ buildHandshake(_opts) {
20
+ // JSON-RPC 2.0 has no handshake — connection is usable immediately
21
+ return null;
22
+ }
23
+ encodeRequest(req) {
24
+ const frame = {
25
+ jsonrpc: "2.0",
26
+ id: req.id,
27
+ method: req.method,
28
+ };
29
+ if (req.params && Object.keys(req.params).length > 0) {
30
+ frame.params = req.params;
31
+ }
32
+ return JSON.stringify(frame);
33
+ }
34
+ parseMessage(raw) {
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(raw);
38
+ }
39
+ catch {
40
+ return { kind: "unknown", raw };
41
+ }
42
+ if (!parsed || typeof parsed !== "object") {
43
+ return { kind: "unknown", raw: parsed };
44
+ }
45
+ const msg = parsed;
46
+ // Must be JSON-RPC 2.0
47
+ if (msg.jsonrpc !== "2.0") {
48
+ return { kind: "unknown", raw: parsed };
49
+ }
50
+ // Response (has id)
51
+ if ("id" in msg && msg.id !== undefined) {
52
+ const rpcMsg = msg;
53
+ const response = {
54
+ id: String(rpcMsg.id),
55
+ ok: !("error" in msg),
56
+ result: rpcMsg.result,
57
+ };
58
+ if (rpcMsg.error) {
59
+ response.error = {
60
+ code: rpcMsg.error.code,
61
+ message: rpcMsg.error.message,
62
+ data: rpcMsg.error.data,
63
+ };
64
+ }
65
+ return { kind: "response", response };
66
+ }
67
+ // Notification (no id, has method) — map to event
68
+ if ("method" in msg && !("id" in msg)) {
69
+ const notif = msg;
70
+ const event = {
71
+ event: notif.method,
72
+ payload: notif.params,
73
+ };
74
+ return { kind: "event", event };
75
+ }
76
+ return { kind: "unknown", raw: parsed };
77
+ }
78
+ isHandshakeResponse(_raw) {
79
+ // JSON-RPC has no handshake — return null to indicate N/A
80
+ return null;
81
+ }
82
+ }
83
+ //# sourceMappingURL=jsonrpc-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonrpc-protocol.js","sourceRoot":"","sources":["../../src/protocols/jsonrpc-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqCH,kEAAkE;AAElE,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,SAAS,CAAC;IAE1B,cAAc,CAAC,KAAuB;QACpC,mEAAmE;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa,CAAC,GAAmB;QAC/B,MAAM,KAAK,GAAmB;YAC5B,OAAO,EAAE,KAAK;YACd,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC;QACF,IAAI,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,YAAY,CAAC,GAAW;QACtB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAC1C,CAAC;QAED,MAAM,GAAG,GAAG,MAAiC,CAAC;QAE9C,uBAAuB;QACvB,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC1B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAC1C,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAI,IAAI,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,GAAiC,CAAC;YACjD,MAAM,QAAQ,GAAoB;gBAChC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACrB,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC;YACF,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,QAAQ,CAAC,KAAK,GAAG;oBACf,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;oBACvB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;oBAC7B,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;iBACxB,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QACxC,CAAC;QAED,kDAAkD;QAClD,IAAI,QAAQ,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,GAAqC,CAAC;YACpD,MAAM,KAAK,GAAiB;gBAC1B,KAAK,EAAE,KAAK,CAAC,MAAM;gBACnB,OAAO,EAAE,KAAK,CAAC,MAAM;aACtB,CAAC;YACF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAClC,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;IAED,mBAAmB,CAAC,IAAY;QAC9B,0DAA0D;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * OpenClaw native protocol adapter.
3
+ *
4
+ * Implements the OpenClaw Gateway WebSocket protocol as documented in:
5
+ * https://github.com/openclaw/openclaw/blob/main/docs/gateway/protocol.md
6
+ *
7
+ * Wire format:
8
+ * Request: { type: "req", id: string, method: string, params?: unknown }
9
+ * Response: { type: "res", id: string, ok: boolean, payload?: unknown, error?: ErrorShape }
10
+ * Event: { type: "event", event: string, payload?: unknown, seq?: number }
11
+ *
12
+ * Connection lifecycle:
13
+ * 1. Gateway may send a "connect.challenge" event with a nonce
14
+ * 2. Client MUST send a "connect" request as the first frame
15
+ * 3. Gateway responds with hello-ok (ok: true) or error + close
16
+ * 4. After handshake, normal req/res flow
17
+ *
18
+ * Key differences from JSON-RPC 2.0:
19
+ * - Uses `type: "req"` instead of `jsonrpc: "2.0"`
20
+ * - Uses `ok: boolean` + `payload` instead of `result`
21
+ * - String IDs only (not numeric)
22
+ * - `additionalProperties: false` — no extra keys allowed
23
+ * - Mandatory connect handshake as first frame
24
+ */
25
+ import type { ProtocolAdapter, GatewayRequest, ParsedMessage, HandshakeOptions } from "./types.js";
26
+ export declare class OpenClawProtocol implements ProtocolAdapter {
27
+ readonly name = "openclaw";
28
+ buildHandshake(opts: HandshakeOptions): string;
29
+ encodeRequest(req: GatewayRequest): string;
30
+ parseMessage(raw: string): ParsedMessage;
31
+ isHandshakeResponse(raw: string): boolean | null;
32
+ }
33
+ //# sourceMappingURL=openclaw-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw-protocol.d.ts","sourceRoot":"","sources":["../../src/protocols/openclaw-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,aAAa,EACb,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAwCpB,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,cAAc;IAE3B,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM;IAwB9C,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM;IAY1C,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IA8CxC,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;CA0BjD"}