@tonytongx/harmony-channel 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenClaw Community
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,92 @@
1
+ # @tonytongx/harmony-channel
2
+
3
+ OpenClaw Channel plugin for HarmonyOS PC - WebSocket bridge for AI chat integration.
4
+
5
+ ## Features
6
+
7
+ - 🔌 **Pure WebSocket** - Single connection for all communication
8
+ - 🔒 **Token Auth** - Secure device authentication
9
+ - 📱 **HarmonyOS Ready** - Designed for 2in1 PC devices
10
+ - ⚡ **Real-time** - Instant message delivery
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ openclaw plugins install @tonytongx/harmony-channel
16
+ ```
17
+
18
+ Or install from source:
19
+
20
+ ```bash
21
+ openclaw plugins install -l ./openclaw-harmony-channel-v2
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ Add to your `~/.openclaw/openclaw.json`:
27
+
28
+ ```json
29
+ {
30
+ "channels": {
31
+ "harmony": {
32
+ "enabled": true,
33
+ "wsPort": 18790,
34
+ "token": "your-secure-token",
35
+ "dmPolicy": "open"
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Or use the wizard:
42
+
43
+ ```bash
44
+ openclaw channels configure harmony
45
+ ```
46
+
47
+ ## HarmonyOS Connection
48
+
49
+ ```typescript
50
+ const ws = new WebSocket(
51
+ 'ws://your-server:18790?deviceId=my-device&token=your-token'
52
+ );
53
+
54
+ // Send message
55
+ ws.send(JSON.stringify({
56
+ type: 'session.send',
57
+ id: 'req-1',
58
+ sessionKey: 'main',
59
+ payload: { message: 'Hello!' }
60
+ }));
61
+ ```
62
+
63
+ ## Protocol
64
+
65
+ ### Connection URL
66
+ ```
67
+ ws://host:port?deviceId=<id>&token=<token>
68
+ ```
69
+
70
+ ### Message Types
71
+
72
+ | Type | Direction | Description |
73
+ |------|-----------|-------------|
74
+ | `connected` | S→C | Connection established |
75
+ | `session.list` | C↔S | List sessions |
76
+ | `session.history` | C↔S | Get history |
77
+ | `session.send` | C→S | Send message |
78
+ | `session.send.ack` | S→C | Message received |
79
+ | `message` | S→C | AI response |
80
+ | `ping/pong` | C↔S | Keep-alive |
81
+
82
+ ## Development
83
+
84
+ ```bash
85
+ npm install
86
+ npm run build
87
+ npm run dev
88
+ ```
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,33 @@
1
+ import type { ChannelPlugin } from "openclaw/plugin-sdk";
2
+ export interface HarmonyConfig {
3
+ enabled?: boolean;
4
+ wsPort?: number;
5
+ token?: string;
6
+ dmPolicy?: "open" | "pairing" | "allowlist";
7
+ allowFrom?: string[];
8
+ }
9
+ export interface HarmonyAccount {
10
+ accountId: string;
11
+ enabled: boolean;
12
+ configured: boolean;
13
+ config: HarmonyConfig;
14
+ }
15
+ export interface HarmonyMessage {
16
+ type: string;
17
+ id?: string;
18
+ payload?: Record<string, unknown>;
19
+ sessionKey?: string;
20
+ }
21
+ export declare const harmonyPlugin: ChannelPlugin<HarmonyAccount>;
22
+ declare const plugin: {
23
+ id: string;
24
+ name: string;
25
+ description: string;
26
+ register(api: {
27
+ registerChannel: (p: {
28
+ plugin: typeof harmonyPlugin;
29
+ }) => void;
30
+ }): void;
31
+ };
32
+ export default plugin;
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,qBAAqB,CAAC;AAO7B,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAoUD,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,cAAc,CAyLvD,CAAC;AAIF,QAAA,MAAM,MAAM;;;;kBAKI;QAAE,eAAe,EAAE,CAAC,CAAC,EAAE;YAAE,MAAM,EAAE,OAAO,aAAa,CAAA;SAAE,KAAK,IAAI,CAAA;KAAE;CAGjF,CAAC;AAEF,eAAe,MAAM,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,424 @@
1
+ import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk";
2
+ import { WebSocketServer, WebSocket } from "ws";
3
+ import { URL } from "url";
4
+ // ==================== 全局状态 ====================
5
+ const wsServers = new Map();
6
+ const connections = new Map();
7
+ const connectionCounts = new Map();
8
+ // ==================== 工具函数 ====================
9
+ function getHarmonyConfig(cfg) {
10
+ return cfg.channels?.harmony || {};
11
+ }
12
+ function resolveAccount(cfg, accountId) {
13
+ const config = getHarmonyConfig(cfg);
14
+ return {
15
+ accountId,
16
+ enabled: config.enabled ?? false,
17
+ configured: !!(config.wsPort && config.token),
18
+ config
19
+ };
20
+ }
21
+ // ==================== WebSocket 处理器 ====================
22
+ async function handleClientMessage(ws, deviceId, message, runtime, cfg) {
23
+ const log = runtime?.log ?? console.log;
24
+ log(`[harmony] ${deviceId}: ${message.type}`);
25
+ switch (message.type) {
26
+ case "ping": {
27
+ ws.send(JSON.stringify({ type: "pong" }));
28
+ break;
29
+ }
30
+ case "session.list": {
31
+ // TODO: 从 OpenClaw Gateway 获取会话列表
32
+ ws.send(JSON.stringify({
33
+ type: "session.list",
34
+ id: message.id,
35
+ payload: { success: true, sessions: [] }
36
+ }));
37
+ break;
38
+ }
39
+ case "session.history": {
40
+ // TODO: 从 OpenClaw Gateway 获取历史记录
41
+ ws.send(JSON.stringify({
42
+ type: "session.history",
43
+ id: message.id,
44
+ sessionKey: message.sessionKey,
45
+ payload: { success: true, messages: [] }
46
+ }));
47
+ break;
48
+ }
49
+ case "session.send": {
50
+ const text = message.payload?.message || "";
51
+ const sessionKey = message.sessionKey || "main";
52
+ if (!text) {
53
+ ws.send(JSON.stringify({
54
+ type: "session.send",
55
+ id: message.id,
56
+ payload: { success: false, error: "Empty message" }
57
+ }));
58
+ return;
59
+ }
60
+ // 发送 ACK
61
+ ws.send(JSON.stringify({
62
+ type: "session.send.ack",
63
+ sessionKey,
64
+ payload: { received: true }
65
+ }));
66
+ // TODO: 转发到 OpenClaw Gateway
67
+ log(`[harmony] Forwarding to ${sessionKey}: ${text.substring(0, 50)}...`);
68
+ ws.send(JSON.stringify({
69
+ type: "session.send",
70
+ id: message.id,
71
+ payload: { success: true }
72
+ }));
73
+ break;
74
+ }
75
+ default: {
76
+ log(`[harmony] Unknown type: ${message.type}`);
77
+ }
78
+ }
79
+ }
80
+ // ==================== 监控器 ====================
81
+ async function startMonitor(cfg, accountId, runtime, abortSignal) {
82
+ const account = resolveAccount(cfg, accountId);
83
+ const log = runtime?.log ?? console.log;
84
+ const error = runtime?.error ?? console.error;
85
+ const port = account.config.wsPort ?? 18790;
86
+ const token = account.config.token ?? "harmony-default-token";
87
+ log(`[harmony:${accountId}] Starting WebSocket server on port ${port}`);
88
+ const wss = new WebSocketServer({ port });
89
+ wsServers.set(accountId, wss);
90
+ connectionCounts.set(accountId, 0);
91
+ return new Promise((resolve, reject) => {
92
+ const cleanup = () => {
93
+ wss.close();
94
+ wsServers.delete(accountId);
95
+ connections.forEach((ws, id) => {
96
+ if (id.startsWith(`${accountId}:`)) {
97
+ ws.close();
98
+ connections.delete(id);
99
+ }
100
+ });
101
+ connectionCounts.delete(accountId);
102
+ };
103
+ abortSignal?.addEventListener("abort", () => {
104
+ log(`[harmony:${accountId}] Stopping server`);
105
+ cleanup();
106
+ resolve();
107
+ }, { once: true });
108
+ wss.on("connection", (ws, req) => {
109
+ try {
110
+ const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
111
+ const deviceId = url.searchParams.get("deviceId");
112
+ const clientToken = url.searchParams.get("token");
113
+ if (!deviceId) {
114
+ ws.close(1008, "Missing deviceId");
115
+ return;
116
+ }
117
+ if (clientToken !== token) {
118
+ ws.close(1008, "Invalid token");
119
+ return;
120
+ }
121
+ const connId = `${accountId}:${deviceId}`;
122
+ connections.set(connId, ws);
123
+ const count = (connectionCounts.get(accountId) ?? 0) + 1;
124
+ connectionCounts.set(accountId, count);
125
+ log(`[harmony] Device connected: ${deviceId} (total: ${count})`);
126
+ // 发送连接成功消息
127
+ ws.send(JSON.stringify({
128
+ type: "connected",
129
+ payload: { deviceId, timestamp: Date.now() }
130
+ }));
131
+ ws.on("message", (data) => {
132
+ try {
133
+ const msg = JSON.parse(data.toString());
134
+ void handleClientMessage(ws, deviceId, msg, runtime, cfg);
135
+ }
136
+ catch (err) {
137
+ error(`[harmony] Invalid message from ${deviceId}: ${err}`);
138
+ }
139
+ });
140
+ ws.on("close", () => {
141
+ connections.delete(connId);
142
+ const current = (connectionCounts.get(accountId) ?? 0) - 1;
143
+ connectionCounts.set(accountId, Math.max(0, current));
144
+ log(`[harmony] Device disconnected: ${deviceId}`);
145
+ });
146
+ ws.on("error", (err) => {
147
+ error(`[harmony] WebSocket error for ${deviceId}: ${err}`);
148
+ });
149
+ }
150
+ catch (err) {
151
+ error(`[harmony] Connection error: ${err}`);
152
+ ws.close(1011, "Internal error");
153
+ }
154
+ });
155
+ wss.on("error", (err) => {
156
+ error(`[harmony:${accountId}] Server error: ${err}`);
157
+ reject(err);
158
+ });
159
+ wss.on("listening", () => {
160
+ log(`[harmony:${accountId}] Server listening on port ${port}`);
161
+ });
162
+ });
163
+ }
164
+ // ==================== 消息发送适配器 ====================
165
+ const outboundAdapter = {
166
+ deliveryMode: "direct",
167
+ chunker: (text) => [text],
168
+ chunkerMode: "raw",
169
+ textChunkLimit: 10000,
170
+ async sendText({ cfg, to, text }) {
171
+ const deviceId = to.replace(/^device:/, "");
172
+ const ws = connections.get(deviceId);
173
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
174
+ throw new Error(`Device ${deviceId} not connected`);
175
+ }
176
+ ws.send(JSON.stringify({
177
+ type: "message",
178
+ payload: { text, role: "assistant", timestamp: Date.now() }
179
+ }));
180
+ return {
181
+ channel: "harmony",
182
+ messageId: `harmony_${Date.now()}`,
183
+ chatId: deviceId
184
+ };
185
+ },
186
+ async sendMedia() {
187
+ throw new Error("Media not supported");
188
+ }
189
+ };
190
+ // ==================== 健康检查 ====================
191
+ async function probeAccount(account) {
192
+ const wsPort = account.config.wsPort;
193
+ if (!wsPort) {
194
+ return { ok: false, error: "WebSocket port not configured" };
195
+ }
196
+ if (!account.config.token) {
197
+ return { ok: false, error: "Token not configured" };
198
+ }
199
+ return { ok: true, wsPort };
200
+ }
201
+ // ==================== 引导配置 ====================
202
+ const onboardingAdapter = {
203
+ async collectInteractive() {
204
+ return {
205
+ fields: [
206
+ {
207
+ key: "wsPort",
208
+ label: "WebSocket Port",
209
+ type: "number",
210
+ defaultValue: 18790,
211
+ required: true
212
+ },
213
+ {
214
+ key: "token",
215
+ label: "Authentication Token",
216
+ type: "string",
217
+ defaultValue: "harmony-default-token",
218
+ required: true
219
+ }
220
+ ]
221
+ };
222
+ },
223
+ buildConfigFromAnswers(answers) {
224
+ return {
225
+ channels: {
226
+ harmony: {
227
+ enabled: true,
228
+ wsPort: answers.wsPort ?? 18790,
229
+ token: answers.token ?? "harmony-default-token"
230
+ }
231
+ }
232
+ };
233
+ },
234
+ async verify(config) {
235
+ const harmonyCfg = config.channels?.harmony;
236
+ if (!harmonyCfg?.wsPort) {
237
+ return { ok: false, error: "WebSocket port required" };
238
+ }
239
+ if (!harmonyCfg?.token) {
240
+ return { ok: false, error: "Token required" };
241
+ }
242
+ return { ok: true };
243
+ }
244
+ };
245
+ // ==================== Channel 插件 ====================
246
+ const meta = {
247
+ id: "harmony",
248
+ label: "HarmonyOS",
249
+ selectionLabel: "HarmonyOS PC (鸿蒙)",
250
+ docsPath: "/channels/harmony",
251
+ docsLabel: "harmony",
252
+ blurb: "HarmonyOS PC integration via WebSocket.",
253
+ aliases: ["harmonyos"],
254
+ order: 100
255
+ };
256
+ export const harmonyPlugin = {
257
+ id: "harmony",
258
+ meta,
259
+ pairing: {
260
+ idLabel: "harmonyDeviceId",
261
+ normalizeAllowEntry: (entry) => entry.replace(/^harmony:/i, ""),
262
+ notifyApproval: async ({ cfg, id }) => {
263
+ console.log(`[harmony] Device ${id} approved`);
264
+ }
265
+ },
266
+ capabilities: {
267
+ chatTypes: ["direct"],
268
+ polls: false,
269
+ threads: false,
270
+ media: false,
271
+ reactions: false,
272
+ edit: false,
273
+ reply: false
274
+ },
275
+ agentPrompt: {
276
+ messageToolHints: () => [
277
+ "- HarmonyOS: Each device connects via WebSocket with deviceId and token.",
278
+ "- HarmonyOS: Messages are received in real-time from connected devices."
279
+ ]
280
+ },
281
+ configSchema: {
282
+ schema: {
283
+ type: "object",
284
+ properties: {
285
+ enabled: { type: "boolean" },
286
+ wsPort: { type: "integer", minimum: 1, maximum: 65535 },
287
+ token: { type: "string" },
288
+ dmPolicy: { type: "string", enum: ["open", "pairing", "allowlist"] },
289
+ allowFrom: { type: "array", items: { type: "string" } }
290
+ }
291
+ }
292
+ },
293
+ config: {
294
+ listAccountIds: () => [DEFAULT_ACCOUNT_ID],
295
+ resolveAccount: (cfg, accountId) => resolveAccount(cfg, accountId),
296
+ defaultAccountId: () => DEFAULT_ACCOUNT_ID,
297
+ setAccountEnabled: ({ cfg, accountId, enabled }) => {
298
+ const harmonyCfg = getHarmonyConfig(cfg);
299
+ return {
300
+ ...cfg,
301
+ channels: {
302
+ ...cfg.channels,
303
+ harmony: {
304
+ ...harmonyCfg,
305
+ enabled
306
+ }
307
+ }
308
+ };
309
+ },
310
+ deleteAccount: ({ cfg }) => {
311
+ const { harmony: _, ...otherChannels } = cfg.channels || {};
312
+ return {
313
+ ...cfg,
314
+ channels: Object.keys(otherChannels).length > 0 ? otherChannels : undefined
315
+ };
316
+ },
317
+ isConfigured: (account) => account.configured,
318
+ describeAccount: (account) => ({
319
+ accountId: account.accountId,
320
+ enabled: account.enabled,
321
+ configured: account.configured,
322
+ wsPort: account.config.wsPort
323
+ }),
324
+ resolveAllowFrom: ({ cfg }) => getHarmonyConfig(cfg).allowFrom || [],
325
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map(s => s.trim()).filter(Boolean)
326
+ },
327
+ security: {
328
+ collectWarnings: ({ cfg, accountId }) => {
329
+ const account = resolveAccount(cfg, accountId);
330
+ const warnings = [];
331
+ if (!account.config.token || account.config.token === "harmony-default-token") {
332
+ warnings.push(`[harmony] Using default token - change for production!`);
333
+ }
334
+ return warnings;
335
+ }
336
+ },
337
+ setup: {
338
+ resolveAccountId: () => DEFAULT_ACCOUNT_ID,
339
+ applyAccountConfig: ({ cfg }) => {
340
+ const harmonyCfg = getHarmonyConfig(cfg);
341
+ return {
342
+ ...cfg,
343
+ channels: {
344
+ ...cfg.channels,
345
+ harmony: {
346
+ ...harmonyCfg,
347
+ enabled: true,
348
+ wsPort: harmonyCfg.wsPort ?? 18790
349
+ }
350
+ }
351
+ };
352
+ }
353
+ },
354
+ onboarding: onboardingAdapter,
355
+ messaging: {
356
+ normalizeTarget: (raw) => {
357
+ const id = raw.replace(/^device:/, "").trim();
358
+ return id ? `device:${id}` : undefined;
359
+ },
360
+ targetResolver: {
361
+ looksLikeId: (id) => /^[a-zA-Z0-9_-]+$/.test(id),
362
+ hint: "device:<deviceId>"
363
+ }
364
+ },
365
+ directory: {
366
+ self: async () => null,
367
+ listPeers: async () => [],
368
+ listGroups: async () => []
369
+ },
370
+ outbound: outboundAdapter,
371
+ status: {
372
+ defaultRuntime: {
373
+ accountId: DEFAULT_ACCOUNT_ID,
374
+ running: false,
375
+ lastStartAt: null,
376
+ lastStopAt: null,
377
+ lastError: null,
378
+ port: null,
379
+ connections: 0
380
+ },
381
+ buildChannelSummary: ({ snapshot }) => ({
382
+ configured: snapshot.configured ?? false,
383
+ running: snapshot.running ?? false,
384
+ lastStartAt: snapshot.lastStartAt ?? null,
385
+ lastStopAt: snapshot.lastStopAt ?? null,
386
+ lastError: snapshot.lastError ?? null,
387
+ port: snapshot.port ?? null,
388
+ connections: snapshot.connections ?? 0
389
+ }),
390
+ probeAccount: async ({ account }) => probeAccount(account),
391
+ buildAccountSnapshot: ({ account, runtime, probe }) => ({
392
+ accountId: account.accountId,
393
+ enabled: account.enabled,
394
+ configured: account.configured,
395
+ wsPort: account.config.wsPort,
396
+ running: runtime?.running ?? false,
397
+ lastStartAt: runtime?.lastStartAt ?? null,
398
+ lastStopAt: runtime?.lastStopAt ?? null,
399
+ lastError: runtime?.lastError ?? null,
400
+ port: runtime?.port ?? null,
401
+ connections: runtime?.connections ?? 0,
402
+ probe
403
+ })
404
+ },
405
+ gateway: {
406
+ startAccount: async (ctx) => {
407
+ const account = resolveAccount(ctx.cfg, ctx.accountId);
408
+ const port = account.config.wsPort ?? 18790;
409
+ ctx.setStatus({ accountId: ctx.accountId, port });
410
+ return startMonitor(ctx.cfg, ctx.accountId, ctx.runtime, ctx.abortSignal);
411
+ }
412
+ }
413
+ };
414
+ // ==================== 插件入口 ====================
415
+ const plugin = {
416
+ id: "harmony-channel",
417
+ name: "HarmonyOS",
418
+ description: "HarmonyOS PC channel plugin",
419
+ register(api) {
420
+ api.registerChannel({ plugin: harmonyPlugin });
421
+ }
422
+ };
423
+ export default plugin;
424
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ {
2
+ "id": "harmony-channel",
3
+ "channels": ["harmony"],
4
+ "skills": [],
5
+ "configSchema": {
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "enabled": { "type": "boolean" },
10
+ "wsPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
11
+ "token": { "type": "string" },
12
+ "dmPolicy": { "type": "string", "enum": ["open", "pairing", "allowlist"] },
13
+ "allowFrom": { "type": "array", "items": { "type": "string" } }
14
+ }
15
+ }
16
+ }
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@tonytongx/harmony-channel",
3
+ "version": "1.0.0",
4
+ "description": "OpenClaw Channel plugin for HarmonyOS PC - WebSocket bridge",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "openclaw.plugin.json",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "clean": "rm -rf dist",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "openclaw",
22
+ "harmonyos",
23
+ "channel",
24
+ "websocket",
25
+ "plugin"
26
+ ],
27
+ "author": "tonytongx <1591114510@qq.com>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/xutongHF/openclaw-harmony-channel.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/xutongHF/openclaw-harmony-channel/issues"
35
+ },
36
+ "homepage": "https://github.com/xutongHF/openclaw-harmony-channel#readme",
37
+ "openclaw": {
38
+ "extensions": ["./dist/index.js"],
39
+ "channel": {
40
+ "id": "harmony",
41
+ "label": "HarmonyOS",
42
+ "selectionLabel": "HarmonyOS PC (鸿蒙)",
43
+ "docsPath": "/channels/harmony",
44
+ "docsLabel": "harmony",
45
+ "blurb": "HarmonyOS PC integration via WebSocket for AI chat.",
46
+ "aliases": ["harmonyos"],
47
+ "order": 100,
48
+ "quickstartAllowFrom": true
49
+ },
50
+ "install": {
51
+ "npmSpec": "@tonytongx/harmony-channel",
52
+ "localPath": "extensions/harmony-channel",
53
+ "defaultChoice": "npm"
54
+ }
55
+ },
56
+ "engines": {
57
+ "node": ">=18.0.0"
58
+ },
59
+ "dependencies": {
60
+ "ws": "^8.16.0"
61
+ },
62
+ "devDependencies": {
63
+ "@types/node": "^20.10.0",
64
+ "@types/ws": "^8.5.10",
65
+ "typescript": "^5.3.0"
66
+ }
67
+ }