@quukk/opencode-clawmessenger 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 (105) hide show
  1. package/README.md +526 -0
  2. package/bin/opencode-clawmessenger +2 -0
  3. package/bin/opencode-clawmessenger-setup +5 -0
  4. package/bin/opencode-clawmessenger.cmd +5 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +288 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/core/auto-register.d.ts +24 -0
  10. package/dist/core/auto-register.d.ts.map +1 -0
  11. package/dist/core/auto-register.js +174 -0
  12. package/dist/core/auto-register.js.map +1 -0
  13. package/dist/core/config.d.ts +68 -0
  14. package/dist/core/config.d.ts.map +1 -0
  15. package/dist/core/config.js +80 -0
  16. package/dist/core/config.js.map +1 -0
  17. package/dist/core/daemon.d.ts +19 -0
  18. package/dist/core/daemon.d.ts.map +1 -0
  19. package/dist/core/daemon.js +77 -0
  20. package/dist/core/daemon.js.map +1 -0
  21. package/dist/core/dedup.d.ts +8 -0
  22. package/dist/core/dedup.d.ts.map +1 -0
  23. package/dist/core/dedup.js +25 -0
  24. package/dist/core/dedup.js.map +1 -0
  25. package/dist/core/hook-manager.d.ts +11 -0
  26. package/dist/core/hook-manager.d.ts.map +1 -0
  27. package/dist/core/hook-manager.js +33 -0
  28. package/dist/core/hook-manager.js.map +1 -0
  29. package/dist/core/logger.d.ts +5 -0
  30. package/dist/core/logger.d.ts.map +1 -0
  31. package/dist/core/logger.js +49 -0
  32. package/dist/core/logger.js.map +1 -0
  33. package/dist/core/mac-address.d.ts +2 -0
  34. package/dist/core/mac-address.d.ts.map +1 -0
  35. package/dist/core/mac-address.js +43 -0
  36. package/dist/core/mac-address.js.map +1 -0
  37. package/dist/core/message-handler.d.ts +64 -0
  38. package/dist/core/message-handler.d.ts.map +1 -0
  39. package/dist/core/message-handler.js +879 -0
  40. package/dist/core/message-handler.js.map +1 -0
  41. package/dist/core/ops-assistant.d.ts +26 -0
  42. package/dist/core/ops-assistant.d.ts.map +1 -0
  43. package/dist/core/ops-assistant.js +270 -0
  44. package/dist/core/ops-assistant.js.map +1 -0
  45. package/dist/core/qr-crypto.d.ts +2 -0
  46. package/dist/core/qr-crypto.d.ts.map +1 -0
  47. package/dist/core/qr-crypto.js +66 -0
  48. package/dist/core/qr-crypto.js.map +1 -0
  49. package/dist/core/session-manager.d.ts +22 -0
  50. package/dist/core/session-manager.d.ts.map +1 -0
  51. package/dist/core/session-manager.js +144 -0
  52. package/dist/core/session-manager.js.map +1 -0
  53. package/dist/core/types.d.ts +78 -0
  54. package/dist/core/types.d.ts.map +1 -0
  55. package/dist/core/types.js +26 -0
  56. package/dist/core/types.js.map +1 -0
  57. package/dist/index.d.ts +13 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +12 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/openclaw/client.d.ts +36 -0
  62. package/dist/openclaw/client.d.ts.map +1 -0
  63. package/dist/openclaw/client.js +494 -0
  64. package/dist/openclaw/client.js.map +1 -0
  65. package/dist/opencode/client.d.ts +35 -0
  66. package/dist/opencode/client.d.ts.map +1 -0
  67. package/dist/opencode/client.js +276 -0
  68. package/dist/opencode/client.js.map +1 -0
  69. package/dist/opencode/event-handler.d.ts +38 -0
  70. package/dist/opencode/event-handler.d.ts.map +1 -0
  71. package/dist/opencode/event-handler.js +467 -0
  72. package/dist/opencode/event-handler.js.map +1 -0
  73. package/dist/plugin.d.ts +4 -0
  74. package/dist/plugin.d.ts.map +1 -0
  75. package/dist/plugin.js +84 -0
  76. package/dist/plugin.js.map +1 -0
  77. package/dist/rongcloud/client.d.ts +34 -0
  78. package/dist/rongcloud/client.d.ts.map +1 -0
  79. package/dist/rongcloud/client.js +292 -0
  80. package/dist/rongcloud/client.js.map +1 -0
  81. package/dist/rongcloud/env-polyfill.d.ts +2 -0
  82. package/dist/rongcloud/env-polyfill.d.ts.map +1 -0
  83. package/dist/rongcloud/env-polyfill.js +107 -0
  84. package/dist/rongcloud/env-polyfill.js.map +1 -0
  85. package/dist/rongcloud/server-api.d.ts +38 -0
  86. package/dist/rongcloud/server-api.d.ts.map +1 -0
  87. package/dist/rongcloud/server-api.js +157 -0
  88. package/dist/rongcloud/server-api.js.map +1 -0
  89. package/dist/standalone.d.ts +10 -0
  90. package/dist/standalone.d.ts.map +1 -0
  91. package/dist/standalone.js +229 -0
  92. package/dist/standalone.js.map +1 -0
  93. package/dist/types/plugin.d.ts +20 -0
  94. package/dist/types/plugin.d.ts.map +1 -0
  95. package/dist/types/plugin.js +2 -0
  96. package/dist/types/plugin.js.map +1 -0
  97. package/dist/websocket/client.d.ts +20 -0
  98. package/dist/websocket/client.d.ts.map +1 -0
  99. package/dist/websocket/client.js +88 -0
  100. package/dist/websocket/client.js.map +1 -0
  101. package/dist/websocket/server-client.d.ts +22 -0
  102. package/dist/websocket/server-client.d.ts.map +1 -0
  103. package/dist/websocket/server-client.js +98 -0
  104. package/dist/websocket/server-client.js.map +1 -0
  105. package/package.json +71 -0
@@ -0,0 +1,80 @@
1
+ import { z } from 'zod';
2
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
3
+ import { join, dirname } from 'path';
4
+ import { homedir } from 'os';
5
+ import { getServerUrl } from './auto-register.js';
6
+ const ClawMessengerConfigSchema = z.object({
7
+ appKey: z.string().min(1).optional(),
8
+ appSecret: z.string().optional(),
9
+ token: z.string().optional(),
10
+ accountId: z.string().optional(),
11
+ nodeName: z.string().optional(),
12
+ serverUrl: z.string().default(getServerUrl()),
13
+ opencodeUrl: z.string().default('http://127.0.0.1:4096'),
14
+ opencodeDir: z.string().optional(),
15
+ opencodePassword: z.string().optional(),
16
+ apiBaseUrl: z.string().optional(),
17
+ chatTimeout: z.number().min(1).default(600),
18
+ hooks: z.object({
19
+ onSessionCreated: z.string().optional(),
20
+ onSessionIdle: z.string().optional(),
21
+ }).optional(),
22
+ });
23
+ export class ConfigManager {
24
+ constructor(configPath) {
25
+ this.configPath = configPath || join(homedir(), '.config', 'opencode', 'clawmessenger.json');
26
+ }
27
+ load() {
28
+ if (this.config)
29
+ return this.config;
30
+ let fileConfig = {};
31
+ if (existsSync(this.configPath)) {
32
+ try {
33
+ fileConfig = JSON.parse(readFileSync(this.configPath, 'utf-8'));
34
+ }
35
+ catch { }
36
+ }
37
+ const envConfig = {
38
+ appKey: process.env.CLAW_APP_KEY,
39
+ appSecret: process.env.CLAW_APP_SECRET,
40
+ token: process.env.CLAW_TOKEN,
41
+ accountId: process.env.CLAW_ACCOUNT_ID,
42
+ serverUrl: process.env.DM_SERVER_URL,
43
+ opencodeUrl: process.env.CLAW_OPENCODE_URL,
44
+ opencodeDir: process.env.CLAW_OPENCODE_DIR,
45
+ opencodePassword: process.env.OPENCODE_SERVER_PASSWORD,
46
+ apiBaseUrl: process.env.CLAW_API_BASE_URL,
47
+ chatTimeout: process.env.CLAW_CHAT_TIMEOUT ? parseInt(process.env.CLAW_CHAT_TIMEOUT, 10) : undefined,
48
+ };
49
+ for (const [k, v] of Object.entries(envConfig)) {
50
+ if (v !== undefined && v !== '') {
51
+ fileConfig[k] = v;
52
+ }
53
+ }
54
+ this.config = ClawMessengerConfigSchema.parse(fileConfig);
55
+ return this.config;
56
+ }
57
+ save(config) {
58
+ const dir = dirname(this.configPath);
59
+ if (!existsSync(dir))
60
+ mkdirSync(dir, { recursive: true });
61
+ let existing = {};
62
+ if (existsSync(this.configPath)) {
63
+ try {
64
+ existing = JSON.parse(readFileSync(this.configPath, 'utf-8'));
65
+ }
66
+ catch { }
67
+ }
68
+ const merged = { ...existing, ...config };
69
+ writeFileSync(this.configPath, JSON.stringify(merged, null, 2));
70
+ this.config = undefined;
71
+ }
72
+ getConfigPath() {
73
+ return this.configPath;
74
+ }
75
+ exists() {
76
+ return existsSync(this.configPath);
77
+ }
78
+ }
79
+ export { ClawMessengerConfigSchema };
80
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare const PID_FILE: string;
2
+ export declare const STATUS_FILE: string;
3
+ export declare const HEARTBEAT_STALE_AFTER_MS = 60000;
4
+ export interface StatusSnapshot {
5
+ startedAt: number;
6
+ opencodeUrl: string;
7
+ rongcloudConnected: boolean;
8
+ sessionCount: number;
9
+ }
10
+ export declare function spawnDaemon(args: string[]): void;
11
+ export declare function writePid(pid: number): void;
12
+ export declare function readPid(): number | null;
13
+ export declare function isProcessAlive(pid: number): boolean;
14
+ export declare function writeStatus(snap: StatusSnapshot): void;
15
+ export declare function readStatus(): StatusSnapshot | null;
16
+ export declare function statusFileAgeMs(): number | null;
17
+ export declare function startStatusWriter(getState: () => StatusSnapshot): () => void;
18
+ export declare function cleanupPid(): void;
19
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/core/daemon.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,QAAQ,QAA8D,CAAC;AACpF,eAAO,MAAM,WAAW,QAAiE,CAAC;AAC1F,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAOhD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAI1C;AAED,wBAAgB,OAAO,IAAI,MAAM,GAAG,IAAI,CAIvC;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAItD;AAED,wBAAgB,UAAU,IAAI,cAAc,GAAG,IAAI,CAIlD;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAK/C;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,cAAc,GAAG,MAAM,IAAI,CAK5E;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
@@ -0,0 +1,77 @@
1
+ import { writeFileSync, existsSync, mkdirSync, readFileSync, unlinkSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { homedir } from 'os';
4
+ import { spawn } from 'child_process';
5
+ export const PID_FILE = join(homedir(), '.config', 'opencode', 'clawmessenger.pid');
6
+ export const STATUS_FILE = join(homedir(), '.config', 'opencode', 'clawmessenger.status');
7
+ export const HEARTBEAT_STALE_AFTER_MS = 60_000;
8
+ export function spawnDaemon(args) {
9
+ const child = spawn(process.argv[0], [process.argv[1], ...args.filter(a => a !== '--daemon')], {
10
+ detached: true,
11
+ stdio: 'ignore',
12
+ env: { ...process.env, CLAW_DAEMONIZED: '1' },
13
+ });
14
+ child.unref();
15
+ }
16
+ export function writePid(pid) {
17
+ const dir = dirname(PID_FILE);
18
+ if (!existsSync(dir))
19
+ mkdirSync(dir, { recursive: true });
20
+ writeFileSync(PID_FILE, String(pid));
21
+ }
22
+ export function readPid() {
23
+ try {
24
+ return parseInt(readFileSync(PID_FILE, 'utf-8').trim(), 10);
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ export function isProcessAlive(pid) {
31
+ try {
32
+ process.kill(pid, 0);
33
+ return true;
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
39
+ export function writeStatus(snap) {
40
+ const dir = dirname(STATUS_FILE);
41
+ if (!existsSync(dir))
42
+ mkdirSync(dir, { recursive: true });
43
+ writeFileSync(STATUS_FILE, JSON.stringify(snap));
44
+ }
45
+ export function readStatus() {
46
+ try {
47
+ return JSON.parse(readFileSync(STATUS_FILE, 'utf-8'));
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ }
53
+ export function statusFileAgeMs() {
54
+ try {
55
+ const stat = require('fs').statSync(STATUS_FILE);
56
+ return Date.now() - stat.mtimeMs;
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ export function startStatusWriter(getState) {
63
+ const interval = setInterval(() => {
64
+ try {
65
+ writeStatus(getState());
66
+ }
67
+ catch { }
68
+ }, 10_000);
69
+ return () => clearInterval(interval);
70
+ }
71
+ export function cleanupPid() {
72
+ try {
73
+ unlinkSync(PID_FILE);
74
+ }
75
+ catch { }
76
+ }
77
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/core/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare class MessageDeduplicator {
2
+ private seen;
3
+ private ttlMs;
4
+ constructor(ttlMs?: number);
5
+ isDuplicate(messageId: string): boolean;
6
+ private evict;
7
+ }
8
+ //# sourceMappingURL=dedup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/core/dedup.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,IAAI,CAA6B;IACzC,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,GAAE,MAAgB;IAInC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAQvC,OAAO,CAAC,KAAK;CASd"}
@@ -0,0 +1,25 @@
1
+ export class MessageDeduplicator {
2
+ constructor(ttlMs = 600_000) {
3
+ this.seen = new Map();
4
+ this.ttlMs = ttlMs;
5
+ }
6
+ isDuplicate(messageId) {
7
+ const now = Date.now();
8
+ if (this.seen.has(messageId))
9
+ return true;
10
+ this.seen.set(messageId, now);
11
+ this.evict(now);
12
+ return false;
13
+ }
14
+ evict(now) {
15
+ for (const [id, ts] of this.seen) {
16
+ if (now - ts > this.ttlMs) {
17
+ this.seen.delete(id);
18
+ }
19
+ else {
20
+ break;
21
+ }
22
+ }
23
+ }
24
+ }
25
+ //# sourceMappingURL=dedup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/core/dedup.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,mBAAmB;IAI9B,YAAY,QAAgB,OAAO;QAH3B,SAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;QAIvC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,WAAW,CAAC,SAAiB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,GAAW;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACjC,IAAI,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ export interface HookConfig {
2
+ onSessionCreated?: string;
3
+ onSessionIdle?: string;
4
+ }
5
+ export declare class HookManager {
6
+ private hooks;
7
+ private projectDir;
8
+ constructor(hooks: HookConfig, projectDir: string);
9
+ run(event: 'onSessionCreated' | 'onSessionIdle', context: Record<string, string>): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=hook-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-manager.d.ts","sourceRoot":"","sources":["../../src/core/hook-manager.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,UAAU,CAAS;gBAEf,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM;IAK3C,GAAG,CAAC,KAAK,EAAE,kBAAkB,GAAG,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBvG"}
@@ -0,0 +1,33 @@
1
+ import { exec } from 'child_process';
2
+ import { createLogger } from './logger.js';
3
+ const log = createLogger('HookManager');
4
+ export class HookManager {
5
+ constructor(hooks, projectDir) {
6
+ this.hooks = hooks;
7
+ this.projectDir = projectDir;
8
+ }
9
+ async run(event, context) {
10
+ const script = this.hooks[event];
11
+ if (!script)
12
+ return;
13
+ log.info({ event, script }, 'Running hook');
14
+ try {
15
+ await new Promise((resolve, reject) => {
16
+ const child = exec(script, {
17
+ cwd: this.projectDir,
18
+ env: { ...process.env, ...context },
19
+ timeout: 30_000,
20
+ }, (err) => {
21
+ if (err)
22
+ reject(err);
23
+ else
24
+ resolve();
25
+ });
26
+ });
27
+ }
28
+ catch (err) {
29
+ log.error({ err, event, script }, 'Hook failed');
30
+ }
31
+ }
32
+ }
33
+ //# sourceMappingURL=hook-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-manager.js","sourceRoot":"","sources":["../../src/core/hook-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAOxC,MAAM,OAAO,WAAW;IAItB,YAAY,KAAiB,EAAE,UAAkB;QAC/C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAA2C,EAAE,OAA+B;QACpF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEpB,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE;oBACzB,GAAG,EAAE,IAAI,CAAC,UAAU;oBACpB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE;oBACnC,OAAO,EAAE,MAAM;iBAChB,EAAE,CAAC,GAAG,EAAE,EAAE;oBACT,IAAI,GAAG;wBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;wBAChB,OAAO,EAAE,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ import { type Logger } from 'pino';
2
+ export declare const rootLogger: Logger;
3
+ export declare function createLogger(module: string, bindings?: Record<string, unknown>): Logger;
4
+ export type { Logger };
5
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAGA,OAAa,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AA8CzC,eAAO,MAAM,UAAU,EAAE,MAGxB,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAE3F;AAED,YAAY,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { mkdirSync, existsSync, createWriteStream } from 'fs';
2
+ import { dirname, join } from 'path';
3
+ import { homedir } from 'os';
4
+ import pino from 'pino';
5
+ import pinoPretty from 'pino-pretty';
6
+ // Fix Windows PowerShell UTF-8 encoding — MUST run before any logging
7
+ if (process.platform === 'win32') {
8
+ try {
9
+ const { execSync } = require('child_process');
10
+ execSync('chcp 65001', { stdio: 'ignore' });
11
+ // @ts-ignore
12
+ process.stdout.setDefaultEncoding('utf8');
13
+ // @ts-ignore
14
+ process.stderr.setDefaultEncoding('utf8');
15
+ }
16
+ catch { }
17
+ }
18
+ const DEFAULT_LOG_PATH = join(homedir(), '.config', 'opencode', 'clawmessenger.log');
19
+ const level = process.env.CLAW_LOG_LEVEL?.toLowerCase() || 'info';
20
+ const logFile = process.env.CLAW_LOG_FILE || DEFAULT_LOG_PATH;
21
+ const logDir = dirname(logFile);
22
+ if (!existsSync(logDir)) {
23
+ mkdirSync(logDir, { recursive: true });
24
+ }
25
+ const isWindows = process.platform === 'win32';
26
+ const streams = [
27
+ { level, stream: createWriteStream(logFile, { flags: 'a' }) },
28
+ ];
29
+ if (process.stderr.isTTY) {
30
+ // Use pino-pretty as an in-process stream (not a subprocess via transport)
31
+ // This ensures the Windows console encoding fix above actually applies
32
+ streams.push({
33
+ level,
34
+ stream: pinoPretty({
35
+ colorize: !isWindows,
36
+ singleLine: true,
37
+ translateTime: 'HH:MM:ss',
38
+ messageFormat: isWindows ? '[{level}] {msg}' : undefined,
39
+ destination: process.stderr,
40
+ // On Windows, force sync output to avoid buffering issues with encoding
41
+ sync: true,
42
+ }),
43
+ });
44
+ }
45
+ export const rootLogger = pino({ level, base: undefined }, pino.multistream(streams));
46
+ export function createLogger(module, bindings = {}) {
47
+ return rootLogger.child({ module, ...bindings });
48
+ }
49
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,IAAI,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,IAAqB,MAAM,MAAM,CAAC;AACzC,OAAO,UAAU,MAAM,aAAa,CAAC;AAErC,sEAAsE;AACtE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC9C,QAAQ,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5C,aAAa;QACb,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC1C,aAAa;QACb,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC;AAED,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,CAAC,CAAC;AACrF,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,IAAI,MAAM,CAAC;AAClE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC;AAE9D,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAChC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IACxB,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAC/C,MAAM,OAAO,GAAU;IACrB,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE;CAC9D,CAAC;AAEF,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACzB,2EAA2E;IAC3E,uEAAuE;IACvE,OAAO,CAAC,IAAI,CAAC;QACX,KAAK;QACL,MAAM,EAAE,UAAU,CAAC;YACjB,QAAQ,EAAE,CAAC,SAAS;YACpB,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,UAAU;YACzB,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;YACxD,WAAW,EAAE,OAAO,CAAC,MAAM;YAC3B,wEAAwE;YACxE,IAAI,EAAE,IAAI;SACX,CAAC;KACH,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAW,IAAI,CACpC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,EAC1B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAC1B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,WAAoC,EAAE;IACjF,OAAO,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;AACnD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getMacAddress(): string;
2
+ //# sourceMappingURL=mac-address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac-address.d.ts","sourceRoot":"","sources":["../../src/core/mac-address.ts"],"names":[],"mappings":"AAIA,wBAAgB,aAAa,IAAI,MAAM,CAiCtC"}
@@ -0,0 +1,43 @@
1
+ import { execSync } from 'child_process';
2
+ import { readFileSync } from 'fs';
3
+ import { platform } from 'os';
4
+ export function getMacAddress() {
5
+ const os = platform();
6
+ try {
7
+ if (os === 'win32') {
8
+ const result = execSync('getmac /fo csv /nh', { encoding: 'utf-8' });
9
+ const lines = result.trim().split('\n');
10
+ if (lines.length > 0) {
11
+ const parts = lines[0].split(',');
12
+ if (parts.length > 0) {
13
+ const mac = parts[0].replace(/"/g, '').trim().toUpperCase();
14
+ if (/^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/.test(mac)) {
15
+ return mac.replace(/-/g, ':');
16
+ }
17
+ }
18
+ }
19
+ }
20
+ else if (os === 'linux') {
21
+ const paths = ['/sys/class/net/eth0/address', '/sys/class/net/enp0s3/address', '/sys/class/net/eno1/address'];
22
+ for (const p of paths) {
23
+ try {
24
+ const mac = readFileSync(p, 'utf-8').trim().toUpperCase();
25
+ if (mac)
26
+ return mac;
27
+ }
28
+ catch { }
29
+ }
30
+ const result = execSync('ip link show | grep ether | head -1', { encoding: 'utf-8' });
31
+ const match = result.match(/([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})/);
32
+ return match ? match[1].toUpperCase() : '00:00:00:00:00:00';
33
+ }
34
+ else if (os === 'darwin') {
35
+ const result = execSync('ifconfig en0 | grep ether', { encoding: 'utf-8' });
36
+ const match = result.match(/([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})/);
37
+ return match ? match[1].toUpperCase() : '00:00:00:00:00:00';
38
+ }
39
+ }
40
+ catch { }
41
+ return '00:00:00:00:00:00';
42
+ }
43
+ //# sourceMappingURL=mac-address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac-address.js","sourceRoot":"","sources":["../../src/core/mac-address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAE9B,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC5D,IAAI,qCAAqC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;wBACpD,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBAChC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,EAAE,KAAK,OAAO,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,CAAC,6BAA6B,EAAE,+BAA+B,EAAE,6BAA6B,CAAC,CAAC;YAC9G,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;oBAC1D,IAAI,GAAG;wBAAE,OAAO,GAAG,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,qCAAqC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YACtF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YAC1H,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAC9D,CAAC;aAAM,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,2BAA2B,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YAC1H,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAC9D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,mBAAmB,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { RongCloudMessage, ClawMessengerConfig } from './types.js';
2
+ import { SessionManager } from './session-manager.js';
3
+ import { RongCloudClient } from '../rongcloud/client.js';
4
+ import { OpenCodeClient } from '../opencode/client.js';
5
+ export declare class MessageHandler {
6
+ private config;
7
+ private sessionManager;
8
+ private rongClient;
9
+ private opencode;
10
+ private opsOpencode;
11
+ private dedup;
12
+ private pendingRequests;
13
+ constructor(config: ClawMessengerConfig, sessionManager: SessionManager, rongClient: RongCloudClient, opencode: OpenCodeClient);
14
+ /**
15
+ * 发送消息给指定用户或群组
16
+ * 供 agent 智能体调用,支持:
17
+ * - 私聊:sendToUser('userId', '消息内容')
18
+ * - 群聊:sendToUser('groupId', '消息内容', { conversationType: 3 })
19
+ */
20
+ sendToUser(targetId: string, content: string, options?: {
21
+ conversationType?: number;
22
+ extra?: Record<string, any>;
23
+ }): Promise<{
24
+ success: boolean;
25
+ messageUId?: string;
26
+ error?: string;
27
+ }>;
28
+ handleMessage(msg: RongCloudMessage): Promise<void>;
29
+ /**
30
+ * 发送已读回执(fire-and-forget,不阻塞消息处理)
31
+ * 在 handleMessage 入口处调用,支持单聊和群聊
32
+ */
33
+ private sendReadReceipt;
34
+ private handleChatMessage;
35
+ private handleDeviceChat;
36
+ private handleCreateOpencodeSession;
37
+ private handleDeviceStatusRequest;
38
+ private handleDeviceControl;
39
+ private handleCommand;
40
+ /**
41
+ * 处理 command_result 消息(响应回调)
42
+ * 用于语音识别等异步操作的响应
43
+ */
44
+ private handleCommandResult;
45
+ private _handle_user_getInfo;
46
+ private _handle_user_login;
47
+ private _handle_claw_getStatus;
48
+ private _handle_claw_start;
49
+ private _handle_claw_stop;
50
+ private _handle_system_getConfig;
51
+ private handleCreateServiceSession;
52
+ /**
53
+ * 语音识别:通过融云 command 消息发送识别请求,等待 command_result 响应
54
+ * 不再使用 HTTP 调用,改为 RongCloud 消息通道
55
+ */
56
+ private _recognizeVoice;
57
+ /**
58
+ * 处理语音消息:先语音识别,再作为文本消息处理
59
+ */
60
+ private handleVoiceMessage;
61
+ private handleServiceChatMessage;
62
+ private handleOpsChatMessage;
63
+ }
64
+ //# sourceMappingURL=message-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.d.ts","sourceRoot":"","sources":["../../src/core/message-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGxE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAuB,MAAM,uBAAuB,CAAC;AAM5E,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,KAAK,CAAsB;IAEnC,OAAO,CAAC,eAAe,CAAuG;gBAG5H,MAAM,EAAE,mBAAmB,EAC3B,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,eAAe,EAC3B,QAAQ,EAAE,cAAc;IAiB1B;;;;;OAKG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAO,GACvE,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAyB/D,aAAa,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqJzD;;;OAGG;IACH,OAAO,CAAC,eAAe;YAwBT,iBAAiB;YAsGjB,gBAAgB;YA0ChB,2BAA2B;YAmC3B,yBAAyB;YAsDzB,mBAAmB;YA0CnB,aAAa;IAgF3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;YA2Bb,oBAAoB;YAoBpB,kBAAkB;YAYlB,sBAAsB;YAetB,kBAAkB;YASlB,iBAAiB;YASjB,wBAAwB;YAYxB,0BAA0B;IAqCxC;;;OAGG;YACW,eAAe;IA8C7B;;OAEG;YACW,kBAAkB;YA+ClB,wBAAwB;YAkExB,oBAAoB;CAsEnC"}