phoneclaw-connector 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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,434 @@
1
+ import { DeviceManager } from './device.js';
2
+ import { RelayClient } from './relay.js';
3
+ import { GatewayClient } from './gateway.js';
4
+ import { PairingManager } from './pairing.js';
5
+ import { DeviceAuthStore } from './device-auth-store.js';
6
+ import { promises as fs } from 'fs';
7
+ import { join, dirname } from 'path';
8
+ import { fileURLToPath } from 'url';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ const CONFIG_DIR = join(__dirname, '..');
12
+ class PhoneClawSkill {
13
+ deviceManager;
14
+ relayClient = null;
15
+ gatewayClient = null;
16
+ pairingManager;
17
+ config = null;
18
+ activeSessions = new Map();
19
+ constructor() {
20
+ this.deviceManager = new DeviceManager();
21
+ this.pairingManager = new PairingManager();
22
+ }
23
+ async initialize() {
24
+ console.log('[PhoneClawSkill] Initializing...');
25
+ // Load config
26
+ await this.loadConfig();
27
+ // Get device info
28
+ const deviceInfo = await this.deviceManager.getDeviceInfo();
29
+ console.log(`[PhoneClawSkill] Device ID: ${deviceInfo.deviceId}`);
30
+ // Connect to Gateway
31
+ await this.connectGateway();
32
+ // Connect to Relay
33
+ await this.connectRelay();
34
+ // Setup message handlers
35
+ this.setupHandlers();
36
+ console.log('[PhoneClawSkill] Initialization complete');
37
+ }
38
+ async loadConfig() {
39
+ try {
40
+ const configPath = join(__dirname, '..', 'config.json');
41
+ const data = await fs.readFile(configPath, 'utf-8');
42
+ this.config = JSON.parse(data);
43
+ }
44
+ catch (error) {
45
+ console.error('[PhoneClawSkill] Failed to load config:', error);
46
+ throw new Error('Config file not found. Please run setup first.');
47
+ }
48
+ }
49
+ async connectGateway() {
50
+ if (!this.config) {
51
+ throw new Error('Config not loaded');
52
+ }
53
+ console.log('[PhoneClawSkill] Connecting to OpenClaw Gateway...');
54
+ // Load persistent Ed25519 device identity + device-auth token store.
55
+ // These are required for the gateway to grant operator.write scope.
56
+ const deviceIdentity = await this.deviceManager.getDeviceIdentity();
57
+ console.log(`[PhoneClawSkill] Gateway device identity: ${deviceIdentity.deviceId.slice(0, 16)}...`);
58
+ const deviceAuthStore = new DeviceAuthStore(CONFIG_DIR);
59
+ // Gateway 冷启动时 listen 18789 可能滞后数秒
60
+ // 加重试避免因启动时序问题导致整个 skill 进程退出
61
+ // 每次重试都新建 GatewayClient,避免上一次的 ws 监听器残留
62
+ const maxRetries = 10;
63
+ const baseDelay = 1000;
64
+ let lastError = null;
65
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
66
+ // 清理上一次的 client(如果它还持有失败的 ws)
67
+ this.gatewayClient = new GatewayClient({
68
+ config: this.config,
69
+ deviceIdentity,
70
+ deviceAuthStore,
71
+ });
72
+ try {
73
+ await this.gatewayClient.connect();
74
+ console.log('[PhoneClawSkill] Gateway connected');
75
+ return;
76
+ }
77
+ catch (error) {
78
+ lastError = error;
79
+ if (attempt === maxRetries)
80
+ break;
81
+ const delay = baseDelay * Math.pow(1.5, attempt - 1); // 1, 1.5, 2.25, 3.4, 5.1, 7.6...
82
+ console.warn(`[PhoneClawSkill] Gateway connect failed (attempt ${attempt}/${maxRetries}), ` +
83
+ `retry in ${delay}ms: ${error instanceof Error ? error.message : String(error)}`);
84
+ await new Promise((r) => setTimeout(r, delay));
85
+ }
86
+ }
87
+ throw lastError instanceof Error
88
+ ? lastError
89
+ : new Error('Failed to connect to Gateway');
90
+ }
91
+ async connectRelay() {
92
+ if (!this.config) {
93
+ throw new Error('Config not loaded');
94
+ }
95
+ const deviceInfo = await this.deviceManager.getDeviceInfo();
96
+ console.log('[PhoneClawSkill] Connecting to Relay Server...');
97
+ this.relayClient = new RelayClient(this.config, deviceInfo);
98
+ await this.relayClient.connect();
99
+ console.log('[PhoneClawSkill] Relay connected');
100
+ }
101
+ setupHandlers() {
102
+ if (!this.relayClient || !this.gatewayClient) {
103
+ return;
104
+ }
105
+ // Handle messages from PhoneClaw App
106
+ this.relayClient.on('forward_message', async (message) => {
107
+ await this.handleIncomingMessage(message);
108
+ });
109
+ // Handle pairing requests
110
+ this.relayClient.on('pairing_request', async (message) => {
111
+ await this.handlePairingRequest(message);
112
+ });
113
+ // Handle gateway events (agent run, deltas, completion, errors)
114
+ this.gatewayClient.onEvent('*', (event) => {
115
+ this.handleGatewayEvent(event);
116
+ });
117
+ }
118
+ async handleIncomingMessage(message) {
119
+ const { sessionId, content } = message;
120
+ // Normalize to lowercase to match Gateway's case-insensitive sessionKey
121
+ const normalizedSessionId = sessionId.toLowerCase();
122
+ try {
123
+ console.log(`[PhoneClawSkill] Processing message for session ${normalizedSessionId}`);
124
+ // Call Gateway agent. 流式 chunk 走 gateway event 通道(agent / agent.delta),
125
+ // 不在 req/res 响应里返回。响应仅是 ack { runId, accepted: true, status }。
126
+ this.activeSessions.set(normalizedSessionId, {
127
+ startedAt: Date.now(),
128
+ accumulated: '',
129
+ });
130
+ const ack = await this.gatewayClient.agent(content, normalizedSessionId);
131
+ console.log(`[PhoneClawSkill] Gateway accepted run for ${normalizedSessionId}:`, JSON.stringify(ack));
132
+ // 记录 runId 以便后续 delta/complete 事件能 match 到 session
133
+ const runId = ack?.runId;
134
+ if (runId) {
135
+ const session = this.activeSessions.get(normalizedSessionId);
136
+ if (session)
137
+ session.runId = runId;
138
+ }
139
+ }
140
+ catch (error) {
141
+ console.error('[PhoneClawSkill] Error processing message:', error);
142
+ this.activeSessions.delete(normalizedSessionId);
143
+ this.relayClient.send({
144
+ type: 'message_error',
145
+ sessionId,
146
+ error: error instanceof Error ? error.message : 'Unknown error'
147
+ });
148
+ }
149
+ }
150
+ /**
151
+ * 处理 Gateway 主动 push 的事件。OpenClaw Gateway 在 agent run 期间会按以下节奏推送:
152
+ * - event=chat, payload.state=delta // 流式增量,payload.deltaText 是新片段
153
+ * - event=chat, payload.state=final // 完整消息(不区分流/批)
154
+ * - event=agent, stream=assistant // 助手文本(data.text 累积内容,data.deltaText 增量)
155
+ * - event=agent, stream=lifecycle // 生命周期(data.phase=end 表示 run 结束)
156
+ * - event=agent, stream=compaction // 压缩事件,忽略
157
+ * sessionKey 形如 agent:main:phoneclaw:<我们的 sessionId>,据此匹配 activeSessions。
158
+ */
159
+ handleGatewayEvent(event) {
160
+ const eventName = event?.event ?? '';
161
+ if (eventName !== 'chat' && eventName !== 'agent') {
162
+ return;
163
+ }
164
+ const payload = event.payload ?? {};
165
+ const sessionId = this.resolveSessionId(event);
166
+ if (!sessionId) {
167
+ console.warn(`[PhoneClawSkill] ${eventName} event for unknown session sessionKey=${payload.sessionKey} sessionId=${payload.sessionId}`);
168
+ return;
169
+ }
170
+ const session = this.activeSessions.get(sessionId);
171
+ if (!session) {
172
+ console.warn(`[PhoneClawSkill] ${eventName} event for inactive sessionId=${sessionId} (active=${Array.from(this.activeSessions.keys()).join(',')})`);
173
+ return;
174
+ }
175
+ const state = payload.state ?? '';
176
+ const stream = payload.stream ?? '';
177
+ if (eventName === 'chat' && state === 'delta') {
178
+ // 流式增量 —— 用 deltaText 拼接到累积缓冲区,并推送给 iPhone
179
+ const delta = payload.deltaText ?? '';
180
+ if (delta) {
181
+ session.accumulated += delta;
182
+ console.log(`[PhoneClawSkill] → stream_chunk(${sessionId}) delta=${JSON.stringify(delta).slice(0, 80)}`);
183
+ this.relayClient.send({
184
+ type: 'stream_chunk',
185
+ sessionId,
186
+ content: delta,
187
+ isDone: false,
188
+ });
189
+ }
190
+ return;
191
+ }
192
+ if (eventName === 'chat' && state === 'final') {
193
+ // 完整消息 —— 用 message.content[0].text 兜底覆盖累积内容
194
+ const fullText = this.extractAssistantText(payload.message);
195
+ if (fullText && fullText !== session.accumulated) {
196
+ const delta = fullText.slice(session.accumulated.length);
197
+ if (delta) {
198
+ this.relayClient.send({
199
+ type: 'stream_chunk',
200
+ sessionId,
201
+ content: delta,
202
+ isDone: false,
203
+ });
204
+ }
205
+ session.accumulated = fullText;
206
+ }
207
+ return;
208
+ }
209
+ if (eventName === 'agent' && stream === 'assistant') {
210
+ // 助手文本 —— data.text 是累积内容,data.deltaText 是增量
211
+ const data = payload.data ?? {};
212
+ const deltaText = data.deltaText ?? '';
213
+ const fullText = data.text ?? '';
214
+ if (deltaText) {
215
+ session.accumulated += deltaText;
216
+ console.log(`[PhoneClawSkill] → stream_chunk(${sessionId}) agent.delta=${JSON.stringify(deltaText).slice(0, 80)}`);
217
+ this.relayClient.send({
218
+ type: 'stream_chunk',
219
+ sessionId,
220
+ content: deltaText,
221
+ isDone: false,
222
+ });
223
+ }
224
+ else if (fullText && fullText.length > session.accumulated.length) {
225
+ // 没有增量但累积文本变长了(兜底)
226
+ const newPart = fullText.slice(session.accumulated.length);
227
+ session.accumulated = fullText;
228
+ this.relayClient.send({
229
+ type: 'stream_chunk',
230
+ sessionId,
231
+ content: newPart,
232
+ isDone: false,
233
+ });
234
+ }
235
+ return;
236
+ }
237
+ if (eventName === 'agent' && stream === 'lifecycle') {
238
+ const phase = payload.data?.phase ?? '';
239
+ console.log(`[PhoneClawSkill] agent lifecycle phase=${phase} sessionId=${sessionId}`);
240
+ if (phase === 'end' || phase === 'finished' || phase === 'complete') {
241
+ // 检测空回复(context overflow 等情况)
242
+ const accumulated = session.accumulated || '';
243
+ if (!accumulated.trim()) {
244
+ console.warn(`[PhoneClawSkill] Empty response for session ${sessionId}, possible context overflow`);
245
+ this.activeSessions.delete(sessionId);
246
+ this.relayClient.send({
247
+ type: 'message_error',
248
+ sessionId,
249
+ error: 'SESSION_CONTEXT_OVERFLOW',
250
+ });
251
+ return;
252
+ }
253
+ this.finishSession(sessionId, 'lifecycle end');
254
+ }
255
+ return;
256
+ }
257
+ if (eventName === 'agent' && (state === 'final' || state === 'complete' || state === 'done')) {
258
+ this.finishSession(sessionId, `agent ${state}`);
259
+ return;
260
+ }
261
+ if (eventName === 'agent' && (state === 'error' || state === 'aborted')) {
262
+ const errMsg = payload.errorMessage ??
263
+ (payload.message ? this.extractAssistantText(payload.message) : '') ??
264
+ `Agent run ${state}`;
265
+ console.error(`[PhoneClawSkill] → message_error(${sessionId}): ${errMsg}`);
266
+ this.relayClient.send({
267
+ type: 'message_error',
268
+ sessionId,
269
+ error: errMsg,
270
+ });
271
+ this.activeSessions.delete(sessionId);
272
+ return;
273
+ }
274
+ }
275
+ finishSession(sessionId, reason) {
276
+ if (!this.activeSessions.has(sessionId)) {
277
+ return;
278
+ }
279
+ console.log(`[PhoneClawSkill] → message_complete(${sessionId}) reason=${reason}`);
280
+ // 推一个空的 stream_chunk(isDone=true) 让 iOS 把消息标记为完成
281
+ this.relayClient.send({
282
+ type: 'stream_chunk',
283
+ sessionId,
284
+ content: '',
285
+ isDone: true,
286
+ });
287
+ this.relayClient.send({ type: 'message_complete', sessionId });
288
+ this.activeSessions.delete(sessionId);
289
+ }
290
+ /** 多种来源解析 sessionId:优先 sessionKey 后缀,其次 payload.sessionId */
291
+ resolveSessionId(event) {
292
+ const payload = event.payload ?? {};
293
+ const sessionKey = payload.sessionKey;
294
+ if (sessionKey) {
295
+ const prefix = 'phoneclaw:';
296
+ const idx = sessionKey.indexOf(prefix);
297
+ if (idx !== -1) {
298
+ const id = sessionKey.slice(idx + prefix.length);
299
+ if (id)
300
+ return id.toLowerCase();
301
+ }
302
+ }
303
+ return undefined;
304
+ }
305
+ /** 从 sessionKey 提取 phoneclaw sessionId。形如 agent:main:phoneclaw:<sessionId> */
306
+ resolveSessionIdFromSessionKey(sessionKey) {
307
+ if (!sessionKey)
308
+ return undefined;
309
+ const prefix = 'phoneclaw:';
310
+ const idx = sessionKey.indexOf(prefix);
311
+ if (idx === -1)
312
+ return undefined;
313
+ return sessionKey.slice(idx + prefix.length) || undefined;
314
+ }
315
+ /** 从 chat message content 数组里提取 text */
316
+ extractAssistantText(message) {
317
+ if (!message || !Array.isArray(message.content))
318
+ return '';
319
+ return message.content
320
+ .filter((c) => c?.type === 'text' && typeof c.text === 'string')
321
+ .map((c) => c.text)
322
+ .join('');
323
+ }
324
+ findSessionIdByRunId(runId) {
325
+ if (!runId)
326
+ return undefined;
327
+ for (const [sessionId, session] of this.activeSessions.entries()) {
328
+ if (session.runId === runId)
329
+ return sessionId;
330
+ }
331
+ return undefined;
332
+ }
333
+ async handlePairingRequest(message) {
334
+ const { pairingCode } = message;
335
+ // Validate pairing code
336
+ const pairingInfo = this.pairingManager.validatePairingCode(pairingCode);
337
+ if (!pairingInfo) {
338
+ this.relayClient.send({
339
+ type: 'pairing_response',
340
+ success: false,
341
+ error: 'Invalid or expired pairing code'
342
+ });
343
+ return;
344
+ }
345
+ // Approve pairing
346
+ this.relayClient.send({
347
+ type: 'pairing_response',
348
+ success: true,
349
+ deviceId: pairingInfo.deviceId
350
+ });
351
+ // Clear used pairing code
352
+ this.pairingManager.clearPairingCode(pairingCode);
353
+ console.log('[PhoneClawSkill] Pairing approved');
354
+ }
355
+ async generatePairingCode() {
356
+ const deviceInfo = await this.deviceManager.getDeviceInfo();
357
+ if (!this.config) {
358
+ throw new Error('Config not loaded');
359
+ }
360
+ const pairingInfo = this.pairingManager.generatePairingCode(deviceInfo, this.config);
361
+ const qrCode = await this.pairingManager.generateQRCode(pairingInfo);
362
+ console.log('\n=== PhoneClaw Pairing Code ===');
363
+ console.log(`Code: ${pairingInfo.pairingCode}`);
364
+ console.log(`Expires: ${new Date(pairingInfo.expiresAt).toLocaleString()}`);
365
+ console.log('\nQR Code:');
366
+ console.log(qrCode);
367
+ console.log('==============================\n');
368
+ }
369
+ async getStatus() {
370
+ const deviceInfo = await this.deviceManager.getDeviceInfo();
371
+ const gatewayConnected = this.gatewayClient?.connected || false;
372
+ const relayConnected = this.relayClient?.connected || false;
373
+ console.log('\n=== PhoneClaw Skill Status ===');
374
+ console.log(`Device ID: ${deviceInfo.deviceId}`);
375
+ console.log(`Gateway: ${gatewayConnected ? 'Connected' : 'Disconnected'}`);
376
+ console.log(`Relay: ${relayConnected ? 'Connected' : 'Disconnected'}`);
377
+ console.log(`Active Sessions: ${this.activeSessions.size}`);
378
+ console.log('===============================\n');
379
+ }
380
+ async shutdown() {
381
+ console.log('[PhoneClawSkill] Shutting down...');
382
+ if (this.relayClient) {
383
+ this.relayClient.disconnect();
384
+ }
385
+ if (this.gatewayClient) {
386
+ this.gatewayClient.disconnect();
387
+ }
388
+ console.log('[PhoneClawSkill] Shutdown complete');
389
+ }
390
+ }
391
+ // CLI interface
392
+ async function main() {
393
+ const skill = new PhoneClawSkill();
394
+ const command = process.argv[2];
395
+ try {
396
+ switch (command) {
397
+ case 'start':
398
+ await skill.initialize();
399
+ console.log('[PhoneClawSkill] Running... Press Ctrl+C to stop');
400
+ // Handle graceful shutdown
401
+ process.on('SIGINT', async () => {
402
+ await skill.shutdown();
403
+ process.exit(0);
404
+ });
405
+ process.on('SIGTERM', async () => {
406
+ await skill.shutdown();
407
+ process.exit(0);
408
+ });
409
+ break;
410
+ case 'pair':
411
+ await skill.initialize();
412
+ await skill.generatePairingCode();
413
+ await skill.shutdown();
414
+ break;
415
+ case 'status':
416
+ await skill.initialize();
417
+ await skill.getStatus();
418
+ await skill.shutdown();
419
+ break;
420
+ default:
421
+ console.log('Usage:');
422
+ console.log(' phoneclaw-skill start - Start the skill');
423
+ console.log(' phoneclaw-skill pair - Generate pairing code');
424
+ console.log(' phoneclaw-skill status - Show status');
425
+ break;
426
+ }
427
+ }
428
+ catch (error) {
429
+ console.error('[PhoneClawSkill] Error:', error);
430
+ process.exit(1);
431
+ }
432
+ }
433
+ main();
434
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/pair.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pair.d.ts","sourceRoot":"","sources":["../src/pair.ts"],"names":[],"mappings":""}
package/dist/pair.js ADDED
@@ -0,0 +1,98 @@
1
+ import { PairingManager } from './pairing.js';
2
+ import { RelayClient } from './relay.js';
3
+ import { readFileSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ /**
8
+ * 一次性 pair 流程:
9
+ * 1. 加载 device + config
10
+ * 2. 连接到 relay(必需:否则 server 不知道这个 code)
11
+ * 3. 在本地 + relay 双侧登记 6 位 code
12
+ * 4. 打印 QR + code(手机扫码即可配对)
13
+ * 5. 阻塞 10 分钟,期间 phone 配对成功 / 失败会实时打印
14
+ * 6. 退出
15
+ */
16
+ async function main() {
17
+ const devicePath = join(__dirname, '..', 'device.json');
18
+ const device = JSON.parse(readFileSync(devicePath, 'utf-8'));
19
+ const configPath = join(__dirname, '..', 'config.json');
20
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
21
+ // 1) 准备本地 code
22
+ const pairingManager = new PairingManager();
23
+ const pairingInfo = pairingManager.generatePairingCode(device, config);
24
+ // 2) 连 relay,注册 code,让 server 知道这个 deviceId+code 是合法的
25
+ const relay = new RelayClient(config, device);
26
+ relay.on('pair_response', (msg) => {
27
+ if (msg.success) {
28
+ console.log('\n[pair] Phone paired with this device. Session token issued to phone.');
29
+ }
30
+ else {
31
+ console.log(`\n[pair] Phone pairing failed: ${msg.error}`);
32
+ }
33
+ });
34
+ relay.on('close', () => {
35
+ console.log('[pair] Relay connection closed. Pairing window ended.');
36
+ process.exit(0);
37
+ });
38
+ try {
39
+ await relay.connect();
40
+ console.log(`[pair] Connected to relay ${config.relayServer}`);
41
+ await registerPairingCodeWithRelay(relay, pairingInfo.pairingCode, device.deviceId);
42
+ console.log('[pair] Pairing code registered with relay server.');
43
+ }
44
+ catch (err) {
45
+ console.error('[pair] Failed to register code with relay:', err);
46
+ console.error('[pair] Aborting. Make sure the relay is reachable and the skill is configured correctly.');
47
+ process.exit(1);
48
+ }
49
+ // 3) 打印 QR
50
+ const qrString = await pairingManager.generateQRCode(pairingInfo);
51
+ console.log('\n=== PhoneClaw Pairing Code ===');
52
+ console.log(`Device ID : ${device.deviceId}`);
53
+ console.log(`Relay URL : ${pairingInfo.relayUrl}`);
54
+ console.log(`Code : ${pairingInfo.pairingCode}`);
55
+ console.log(`Expires : ${new Date(pairingInfo.expiresAt).toLocaleString()}`);
56
+ console.log('\nQR Code:');
57
+ console.log(qrString);
58
+ console.log('==============================');
59
+ console.log('Scan the QR with PhoneClaw app, or enter the 6-digit code manually.');
60
+ console.log('This window stays open for 10 minutes. Press Ctrl+C to cancel.\n');
61
+ // 4) 阻塞等配对完成 / 超时
62
+ setTimeout(() => {
63
+ console.log('[pair] Pairing code expired. Exiting.');
64
+ relay.disconnect();
65
+ process.exit(0);
66
+ }, pairingInfo.expiresAt - Date.now());
67
+ }
68
+ function registerPairingCodeWithRelay(relay, pairingCode, deviceId) {
69
+ return new Promise((resolve, reject) => {
70
+ const timer = setTimeout(() => {
71
+ cleanup();
72
+ reject(new Error('Timed out waiting for relay ack'));
73
+ }, 5000);
74
+ function cleanup() {
75
+ clearTimeout(timer);
76
+ relay.off('register_pairing_code_response');
77
+ }
78
+ relay.on('register_pairing_code_response', (msg) => {
79
+ cleanup();
80
+ if (msg.success) {
81
+ resolve();
82
+ }
83
+ else {
84
+ reject(new Error(msg.error || 'relay rejected pairing code'));
85
+ }
86
+ });
87
+ relay.send({
88
+ type: 'register_pairing_code',
89
+ pairingCode,
90
+ deviceId
91
+ });
92
+ });
93
+ }
94
+ main().catch((err) => {
95
+ console.error('[pair] Fatal:', err);
96
+ process.exit(1);
97
+ });
98
+ //# sourceMappingURL=pair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pair.js","sourceRoot":"","sources":["../src/pair.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { DeviceInfo, PairingInfo, SkillConfig } from './types.js';
2
+ export declare class PairingManager {
3
+ private activePairingCodes;
4
+ private readonly CODE_EXPIRY_MS;
5
+ generatePairingCode(deviceInfo: DeviceInfo, config: SkillConfig): PairingInfo;
6
+ generateQRCode(pairingInfo: PairingInfo): Promise<string>;
7
+ generateQRCodeDataURL(pairingInfo: PairingInfo): Promise<string>;
8
+ validatePairingCode(code: string): PairingInfo | null;
9
+ clearPairingCode(code: string): void;
10
+ getActivePairingCodes(): string[];
11
+ }
12
+ //# sourceMappingURL=pairing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../src/pairing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElE,qBAAa,cAAc;IACzB,OAAO,CAAC,kBAAkB,CAAkC;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IAEjD,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW;IAoBvE,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAezD,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IActE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAerD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpC,qBAAqB,IAAI,MAAM,EAAE;CAUlC"}