clawmate 1.4.0 → 1.4.2

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 (42) hide show
  1. package/index.js +441 -442
  2. package/main/ai-bridge.js +59 -59
  3. package/main/ai-connector.js +60 -60
  4. package/main/autostart.js +6 -6
  5. package/main/desktop-path.js +4 -4
  6. package/main/file-command-parser.js +46 -46
  7. package/main/file-ops.js +27 -27
  8. package/main/index.js +17 -17
  9. package/main/ipc-handlers.js +24 -24
  10. package/main/manifest.js +2 -2
  11. package/main/platform.js +16 -16
  12. package/main/smart-file-ops.js +64 -64
  13. package/main/store.js +1 -1
  14. package/main/telegram.js +137 -137
  15. package/main/tray.js +61 -61
  16. package/main/updater.js +13 -13
  17. package/openclaw.plugin.json +1 -1
  18. package/package.json +2 -2
  19. package/preload/preload.js +18 -18
  20. package/renderer/css/effects.css +6 -6
  21. package/renderer/css/pet.css +8 -8
  22. package/renderer/css/speech.css +5 -5
  23. package/renderer/first-run.html +14 -14
  24. package/renderer/index.html +4 -4
  25. package/renderer/js/ai-controller.js +91 -91
  26. package/renderer/js/app.js +24 -24
  27. package/renderer/js/browser-watcher.js +32 -32
  28. package/renderer/js/character.js +33 -33
  29. package/renderer/js/interactions.js +21 -21
  30. package/renderer/js/memory.js +60 -60
  31. package/renderer/js/metrics.js +141 -141
  32. package/renderer/js/mode-manager.js +13 -13
  33. package/renderer/js/pet-engine.js +236 -236
  34. package/renderer/js/speech.js +19 -19
  35. package/renderer/js/state-machine.js +23 -23
  36. package/renderer/js/time-aware.js +15 -15
  37. package/renderer/launcher.html +8 -8
  38. package/shared/constants.js +11 -11
  39. package/shared/messages.js +130 -130
  40. package/shared/personalities.js +44 -44
  41. package/skills/launch-pet/index.js +57 -47
  42. package/skills/launch-pet/skill.json +12 -23
package/main/ai-bridge.js CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
- * AI ClawMate 브릿지
2
+ * AI <-> ClawMate Bridge
3
3
  *
4
- * AI 에이전트가 ClawMate의 역할을 한다.
5
- * - AI ClawMate: 행동 명령, 말풍선, 감정, 이동
6
- * - ClawMate AI: 사용자 이벤트 (클릭, 드래그, 커서, 파일 변화)
4
+ * AI agent serves as ClawMate's brain.
5
+ * - AI -> ClawMate: Action commands, speech bubbles, emotions, movement
6
+ * - ClawMate -> AI: User events (click, drag, cursor, file changes)
7
7
  *
8
- * 통신: WebSocket (로컬 ws://localhost:9320)
9
- * 프로토콜: JSON 메시지
8
+ * Communication: WebSocket (local ws://localhost:9320)
9
+ * Protocol: JSON messages
10
10
  *
11
- * AI 연결 됐을 자율 모드 (기존 FSM) 로 폴백
11
+ * When AI is not connected -> falls back to autonomous mode (existing FSM)
12
12
  */
13
13
  const WebSocket = require('ws');
14
14
  const EventEmitter = require('events');
@@ -17,7 +17,7 @@ class AIBridge extends EventEmitter {
17
17
  constructor() {
18
18
  super();
19
19
  this.wss = null;
20
- this.client = null; // 연결된 AI 에이전트
20
+ this.client = null; // Connected AI agent
21
21
  this.connected = false;
22
22
  this.port = 9320;
23
23
  this.heartbeatInterval = null;
@@ -33,19 +33,19 @@ class AIBridge extends EventEmitter {
33
33
  }
34
34
 
35
35
  /**
36
- * WebSocket 서버 시작 AI 에이전트가 여기에 접속
36
+ * Start WebSocket server -- AI agent connects here
37
37
  */
38
38
  start() {
39
39
  this.wss = new WebSocket.Server({ port: this.port, host: '127.0.0.1' });
40
40
 
41
41
  this.wss.on('connection', (ws) => {
42
- console.log('[AI Bridge] AI 연결됨');
42
+ console.log('[AI Bridge] AI connected');
43
43
  this.client = ws;
44
44
  this.connected = true;
45
45
  this.reconnectAttempts = 0;
46
46
  this.emit('connected');
47
47
 
48
- // AI에 현재 상태 전송
48
+ // Send current state to AI
49
49
  this.send('sync', this.petState);
50
50
 
51
51
  ws.on('message', (data) => {
@@ -53,22 +53,22 @@ class AIBridge extends EventEmitter {
53
53
  const msg = JSON.parse(data.toString());
54
54
  this._handleCommand(msg);
55
55
  } catch (err) {
56
- console.error('[AI Bridge] 메시지 파싱 실패:', err);
56
+ console.error('[AI Bridge] Message parsing failed:', err);
57
57
  }
58
58
  });
59
59
 
60
60
  ws.on('close', () => {
61
- console.log('[AI Bridge] AI 연결 해제');
61
+ console.log('[AI Bridge] AI disconnected');
62
62
  this.client = null;
63
63
  this.connected = false;
64
64
  this.emit('disconnected');
65
65
  });
66
66
 
67
67
  ws.on('error', (err) => {
68
- console.error('[AI Bridge] WebSocket 오류:', err.message);
68
+ console.error('[AI Bridge] WebSocket error:', err.message);
69
69
  });
70
70
 
71
- // 하트비트
71
+ // Heartbeat
72
72
  this.heartbeatInterval = setInterval(() => {
73
73
  if (this.connected) {
74
74
  this.send('heartbeat', { timestamp: Date.now() });
@@ -77,54 +77,54 @@ class AIBridge extends EventEmitter {
77
77
  });
78
78
 
79
79
  this.wss.on('error', (err) => {
80
- console.error('[AI Bridge] 서버 오류:', err.message);
80
+ console.error('[AI Bridge] Server error:', err.message);
81
81
  });
82
82
 
83
- console.log(`[AI Bridge] ws://127.0.0.1:${this.port} 에서 대기 중`);
83
+ console.log(`[AI Bridge] Listening on ws://127.0.0.1:${this.port}`);
84
84
  }
85
85
 
86
86
  /**
87
- * AI에서 명령 처리
87
+ * Handle commands from AI
88
88
  */
89
89
  _handleCommand(msg) {
90
90
  const { type, payload } = msg;
91
91
 
92
92
  switch (type) {
93
- // === 행동 제어 ===
93
+ // === Behavior Control ===
94
94
  case 'action':
95
- // AI 펫의 행동을 직접 지시
95
+ // AI directly commands pet behavior
96
96
  // payload: { state: 'walking'|'excited'|..., duration?: ms }
97
97
  this.emit('action', payload);
98
98
  break;
99
99
 
100
100
  case 'move':
101
- // 특정 위치로 이동
101
+ // Move to specific position
102
102
  // payload: { x, y, speed? }
103
103
  this.emit('move', payload);
104
104
  break;
105
105
 
106
106
  case 'emote':
107
- // 감정 표현
107
+ // Express emotion
108
108
  // payload: { emotion: 'happy'|'curious'|'sleepy'|... }
109
109
  this.emit('emote', payload);
110
110
  break;
111
111
 
112
- // === 말하기 ===
112
+ // === Speech ===
113
113
  case 'speak':
114
- // AI 펫을 통해 사용자에게 말함
114
+ // AI speaks to user through the pet
115
115
  // payload: { text: string, style?: 'normal'|'thought'|'shout' }
116
116
  this.emit('speak', payload);
117
117
  break;
118
118
 
119
119
  case 'think':
120
- // 생각 말풍선 (... 형태)
120
+ // Thought bubble (... form)
121
121
  // payload: { text: string }
122
122
  this.emit('think', payload);
123
123
  break;
124
124
 
125
- // === 파일 작업 ===
125
+ // === File Operations ===
126
126
  case 'carry_file':
127
- // 특정 파일을 집어들도록 지시
127
+ // Command to pick up specific file
128
128
  // payload: { fileName: string, targetX?: number }
129
129
  this.emit('carry_file', payload);
130
130
  break;
@@ -134,134 +134,134 @@ class AIBridge extends EventEmitter {
134
134
  break;
135
135
 
136
136
  case 'smart_file_op':
137
- // 스마트 파일 조작 (텔레그램 또는 AI에서 트리거)
137
+ // Smart file operation (triggered by Telegram or AI)
138
138
  // payload: { phase: 'pick_up'|'drop'|'complete', fileName?, targetName?, ... }
139
139
  this.emit('smart_file_op', payload);
140
140
  break;
141
141
 
142
- // === 외형 변화 ===
142
+ // === Appearance Changes ===
143
143
  case 'evolve':
144
- // 진화 트리거
144
+ // Evolution trigger
145
145
  // payload: { stage: number }
146
146
  this.emit('evolve', payload);
147
147
  break;
148
148
 
149
149
  case 'set_mode':
150
- // 모드 전환
150
+ // Mode switching
151
151
  // payload: { mode: 'pet'|'incarnation' }
152
152
  this.emit('set_mode', payload);
153
153
  break;
154
154
 
155
155
  case 'accessorize':
156
- // 임시 악세사리 추가
156
+ // Add temporary accessory
157
157
  // payload: { type: string, duration?: ms }
158
158
  this.emit('accessorize', payload);
159
159
  break;
160
160
 
161
- // === 공간 이동 명령 ===
161
+ // === Spatial Movement Commands ===
162
162
  case 'jump_to':
163
- // 특정 위치로 점프
163
+ // Jump to specific position
164
164
  // payload: { x, y }
165
165
  this.emit('jump_to', payload);
166
166
  break;
167
167
 
168
168
  case 'rappel':
169
- // 레펠 (천장/벽에서 타고 내려가기)
169
+ // Rappel (descend from ceiling/wall on thread)
170
170
  // payload: {}
171
171
  this.emit('rappel', payload);
172
172
  break;
173
173
 
174
174
  case 'release_thread':
175
- // 레펠 해제 (낙하)
175
+ // Release rappel thread (fall)
176
176
  // payload: {}
177
177
  this.emit('release_thread', payload);
178
178
  break;
179
179
 
180
180
  case 'move_to_center':
181
- // 화면 중앙으로 이동
181
+ // Move to screen center
182
182
  // payload: {}
183
183
  this.emit('move_to_center', payload);
184
184
  break;
185
185
 
186
186
  case 'walk_on_window':
187
- // 특정 윈도우 타이틀바 위로 이동
187
+ // Move onto specific window title bar
188
188
  // payload: { windowId, x, y }
189
189
  this.emit('walk_on_window', payload);
190
190
  break;
191
191
 
192
192
  case 'query_windows':
193
- // 윈도우 위치 정보 요청 main process에서 처리
193
+ // Window position info request -> handled by main process
194
194
  this.emit('query_windows', payload);
195
195
  break;
196
196
 
197
- // === 커스텀 이동 패턴 ===
197
+ // === Custom Movement Patterns ===
198
198
  case 'register_movement':
199
- // AI 커스텀 이동 패턴 등록
199
+ // AI registers custom movement pattern
200
200
  // payload: { name: string, definition: { type: 'waypoints'|'formula'|'sequence', ... } }
201
201
  this.emit('register_movement', payload);
202
202
  break;
203
203
 
204
204
  case 'custom_move':
205
- // 등록된 커스텀 이동 패턴 실행
205
+ // Execute registered custom movement pattern
206
206
  // payload: { name: string, params?: object }
207
207
  this.emit('custom_move', payload);
208
208
  break;
209
209
 
210
210
  case 'stop_custom_move':
211
- // 현재 커스텀 이동 강제 중지
211
+ // Force stop current custom movement
212
212
  // payload: {}
213
213
  this.emit('stop_custom_move', payload);
214
214
  break;
215
215
 
216
216
  case 'list_movements':
217
- // 등록된 이동 패턴 목록 요청 응답은 renderer에서 reportToAI로 전송
217
+ // Request registered movement pattern list -> response sent via renderer's reportToAI
218
218
  // payload: {}
219
219
  this.emit('list_movements', payload);
220
220
  break;
221
221
 
222
- // === 캐릭터 커스터마이징 ===
222
+ // === Character Customization ===
223
223
  case 'set_character':
224
- // AI 생성한 캐릭터 데이터 적용
224
+ // Apply AI-generated character data
225
225
  // payload: { colorMap?: {...}, frames?: {...} }
226
226
  this.emit('set_character', payload);
227
227
  break;
228
228
 
229
229
  case 'reset_character':
230
- // 원래 캐릭터로 리셋
230
+ // Reset to default character
231
231
  this.emit('reset_character', payload);
232
232
  break;
233
233
 
234
234
  case 'set_persona':
235
- // 인격체 전환 (Incarnation 모드)
235
+ // Bot persona switching (Incarnation mode)
236
236
  // payload: { name, personality, speakingStyle, color?, ... }
237
237
  this.emit('set_persona', payload);
238
238
  break;
239
239
 
240
- // === 컨텍스트 질의 ===
240
+ // === Context Queries ===
241
241
  case 'query_state':
242
- // 현재 상태 요청
242
+ // Request current pet state
243
243
  this.send('state_response', this.petState);
244
244
  break;
245
245
 
246
246
  case 'query_screen':
247
- // 화면 정보 요청
247
+ // Request screen info
248
248
  this.emit('query_screen', payload);
249
249
  break;
250
250
 
251
- // === AI 의사결정 결과 ===
251
+ // === AI Decision Result ===
252
252
  case 'ai_decision':
253
- // AI 종합적 의사결정
253
+ // AI's comprehensive decision
254
254
  // payload: { action, speech?, emotion?, reasoning? }
255
255
  this.emit('ai_decision', payload);
256
256
  break;
257
257
 
258
258
  default:
259
- console.log(`[AI Bridge] 없는 명령: ${type}`);
259
+ console.log(`[AI Bridge] Unknown command: ${type}`);
260
260
  }
261
261
  }
262
262
 
263
263
  /**
264
- * AI에 이벤트 전송
264
+ * Send event to AI
265
265
  */
266
266
  send(type, payload) {
267
267
  if (!this.client || this.client.readyState !== WebSocket.OPEN) return false;
@@ -273,7 +273,7 @@ class AIBridge extends EventEmitter {
273
273
  }
274
274
  }
275
275
 
276
- // === 사용자 이벤트 리포트 (ClawMate AI) ===
276
+ // === User Event Reports (ClawMate -> AI) ===
277
277
 
278
278
  reportUserClick(position) {
279
279
  this.send('user_event', {
@@ -335,8 +335,8 @@ class AIBridge extends EventEmitter {
335
335
  }
336
336
 
337
337
  /**
338
- * 메트릭 데이터를 AI에 전송
339
- * 렌더러에서 수집한 동작 품질 메트릭을 AI에 전달
338
+ * Send metrics data to AI
339
+ * Forwards pet behavior quality metrics collected by renderer to AI
340
340
  */
341
341
  reportMetrics(summary) {
342
342
  this.send('metrics_report', {
@@ -345,7 +345,7 @@ class AIBridge extends EventEmitter {
345
345
  });
346
346
  }
347
347
 
348
- // === 상태 업데이트 ===
348
+ // === State Updates ===
349
349
 
350
350
  updatePetState(updates) {
351
351
  Object.assign(this.petState, updates);
@@ -1,15 +1,15 @@
1
1
  /**
2
- * AI 에이전트 측 커넥터
2
+ * AI Agent-side Connector
3
3
  *
4
- * AI ClawMate 접속해서 펫을 조종하는 클라이언트.
5
- * ClawMate 플러그인(index.js)에서 사용됨.
4
+ * Client for AI to connect to ClawMate and control the pet.
5
+ * Used in the ClawMate plugin (index.js).
6
6
  *
7
- * 사용 예:
7
+ * Usage:
8
8
  * const connector = new ClawMateConnector();
9
9
  * await connector.connect();
10
- * connector.speak('안녕! 오늘 거야?');
10
+ * connector.speak('Hello! What are you doing today?');
11
11
  * connector.action('excited');
12
- * connector.onUserEvent((event) => { ... AI 반응 결정 ... });
12
+ * connector.onUserEvent((event) => { ... AI decides reaction ... });
13
13
  */
14
14
  const WebSocket = require('ws');
15
15
  const EventEmitter = require('events');
@@ -27,7 +27,7 @@ class ClawMateConnector extends EventEmitter {
27
27
  }
28
28
 
29
29
  /**
30
- * ClawMate에 접속
30
+ * Connect to ClawMate
31
31
  */
32
32
  connect() {
33
33
  return new Promise((resolve, reject) => {
@@ -73,7 +73,7 @@ class ClawMateConnector extends EventEmitter {
73
73
  case 'pet_state_update':
74
74
  this.petState = payload;
75
75
  this.emit('state_update', payload);
76
- // queryState() Promise 해소
76
+ // Resolve queryState() Promise
77
77
  if (type === 'state_response' && this._stateResolvers.length > 0) {
78
78
  const resolver = this._stateResolvers.shift();
79
79
  resolver(payload);
@@ -81,22 +81,22 @@ class ClawMateConnector extends EventEmitter {
81
81
  break;
82
82
 
83
83
  case 'user_event':
84
- // 사용자 이벤트 AI 반응 결정
84
+ // User event -> AI decides reaction
85
85
  this.emit('user_event', payload);
86
86
  break;
87
87
 
88
88
  case 'screen_capture':
89
- // 화면 캡처 응답 AI 분석
89
+ // Screen capture response -> AI analyzes
90
90
  this.emit('screen_capture', payload);
91
91
  break;
92
92
 
93
93
  case 'window_positions':
94
- // 윈도우 위치 정보 응답 탐험 시스템에서 사용
94
+ // Window position info response -> used by exploration system
95
95
  this.emit('window_positions', payload);
96
96
  break;
97
97
 
98
98
  case 'metrics_report':
99
- // 메트릭 데이터 수신 AI 분석
99
+ // Metrics data received -> AI analyzes
100
100
  this.emit('metrics_report', payload);
101
101
  break;
102
102
 
@@ -115,109 +115,109 @@ class ClawMateConnector extends EventEmitter {
115
115
  }
116
116
  }
117
117
 
118
- // === AI ClawMate 명령 API ===
118
+ // === AI -> ClawMate Command API ===
119
119
 
120
- /** 펫이 말하게 */
120
+ /** Make the pet speak */
121
121
  speak(text, style = 'normal') {
122
122
  return this._send('speak', { text, style });
123
123
  }
124
124
 
125
- /** 펫이 생각하게 (말풍선에 ...) */
125
+ /** Make the pet think (shows ... in speech bubble) */
126
126
  think(text) {
127
127
  return this._send('think', { text });
128
128
  }
129
129
 
130
- /** 행동 변경 */
130
+ /** Change pet behavior */
131
131
  action(state, duration) {
132
132
  return this._send('action', { state, duration });
133
133
  }
134
134
 
135
- /** 특정 위치로 이동 */
135
+ /** Move to specific position */
136
136
  moveTo(x, y, speed) {
137
137
  return this._send('move', { x, y, speed });
138
138
  }
139
139
 
140
- /** 감정 표현 */
140
+ /** Express emotion */
141
141
  emote(emotion) {
142
142
  return this._send('emote', { emotion });
143
143
  }
144
144
 
145
- /** 파일 집어들기 */
145
+ /** Pick up file */
146
146
  carryFile(fileName, targetX) {
147
147
  return this._send('carry_file', { fileName, targetX });
148
148
  }
149
149
 
150
- /** 파일 내려놓기 */
150
+ /** Drop file */
151
151
  dropFile() {
152
152
  return this._send('drop_file', {});
153
153
  }
154
154
 
155
- /** 모드 전환 */
155
+ /** Switch mode */
156
156
  setMode(mode) {
157
157
  return this._send('set_mode', { mode });
158
158
  }
159
159
 
160
- /** 진화 트리거 */
160
+ /** Trigger evolution */
161
161
  evolve(stage) {
162
162
  return this._send('evolve', { stage });
163
163
  }
164
164
 
165
165
  /**
166
- * AI 종합 의사결정 전송
167
- * AI 상황을 분석하고 내린 결정을 한번에 전송
166
+ * Send comprehensive AI decision
167
+ * Sends the AI's analyzed decision in a single message
168
168
  */
169
169
  decide(decision) {
170
170
  return this._send('ai_decision', decision);
171
171
  }
172
172
 
173
- // === 공간 이동 API (펫이 컴퓨터를 ""처럼 돌아다님) ===
173
+ // === Spatial Movement API (pet roams the computer like its "home") ===
174
174
 
175
- /** 특정 위치로 점프 */
175
+ /** Jump to specific position */
176
176
  jumpTo(x, y) {
177
177
  return this._send('jump_to', { x, y });
178
178
  }
179
179
 
180
- /** 레펠 시작 (천장/벽에서 타고 내려감) */
180
+ /** Start rappelling (descend from ceiling/wall on thread) */
181
181
  rappel() {
182
182
  return this._send('rappel', {});
183
183
  }
184
184
 
185
- /** 레펠 해제 (낙하) */
185
+ /** Release rappel thread (fall) */
186
186
  releaseThread() {
187
187
  return this._send('release_thread', {});
188
188
  }
189
189
 
190
- /** 화면 중앙으로 이동 */
190
+ /** Move to screen center */
191
191
  moveToCenter() {
192
192
  return this._send('move_to_center', {});
193
193
  }
194
194
 
195
- /** 특정 윈도우 위로 점프 */
195
+ /** Jump onto specific window */
196
196
  walkOnWindow(windowId, x, y) {
197
197
  return this._send('walk_on_window', { windowId, x, y });
198
198
  }
199
199
 
200
- /** 열린 윈도우 목록 요청 */
200
+ /** Request list of open windows */
201
201
  queryWindows() {
202
202
  return this._send('query_windows', {});
203
203
  }
204
204
 
205
- // === 커스텀 이동 패턴 API ===
205
+ // === Custom Movement Pattern API ===
206
206
 
207
207
  /**
208
- * 커스텀 이동 패턴 등록
209
- * ClawMate에 새로운 이동 패턴을 동적으로 추가
208
+ * Register custom movement pattern
209
+ * Dynamically add new movement patterns to ClawMate
210
210
  *
211
- * @param {string} name - 패턴 이름 (예: 'figure8', 'spiral')
212
- * @param {object} definition - 패턴 정의
211
+ * @param {string} name - Pattern name (e.g., 'figure8', 'spiral')
212
+ * @param {object} definition - Pattern definition
213
213
  * type: 'waypoints' | 'formula' | 'sequence'
214
- * waypoints?: [{x, y, pause?}] 웨이포인트 순차 이동
215
- * formula?: { xAmp, yAmp, xFreq, yFreq, xPhase, yPhase } 수학 궤도
216
- * sequence?: ['zigzag', 'shake'] 기존 패턴 순차 실행
217
- * duration?: number 지속 시간 (ms, formula 타입)
218
- * speed?: number 이동 속도
214
+ * waypoints?: [{x, y, pause?}] -- Sequential waypoint movement
215
+ * formula?: { xAmp, yAmp, xFreq, yFreq, xPhase, yPhase } -- Mathematical orbit
216
+ * sequence?: ['zigzag', 'shake'] -- Execute existing patterns sequentially
217
+ * duration?: number -- Duration (ms, for formula type)
218
+ * speed?: number -- Movement speed
219
219
  *
220
- * 사용 예:
220
+ * Usage:
221
221
  * connector.registerMovement('figure8', {
222
222
  * type: 'formula',
223
223
  * formula: { xAmp: 80, yAmp: 40, xFreq: 1, yFreq: 2 },
@@ -229,14 +229,14 @@ class ClawMateConnector extends EventEmitter {
229
229
  }
230
230
 
231
231
  /**
232
- * 등록된 커스텀 이동 패턴 실행
232
+ * Execute registered custom movement pattern
233
233
  *
234
- * @param {string} name - 실행할 패턴 이름
235
- * 사전 등록 패턴: 'zigzag', 'patrol', 'circle', 'shake', 'dance'
236
- * 또는 registerMovement()로 등록한 커스텀 패턴
237
- * @param {object} params - 실행 파라미터 (패턴별로 다름)
234
+ * @param {string} name - Pattern name to execute
235
+ * Built-in patterns: 'zigzag', 'patrol', 'circle', 'shake', 'dance'
236
+ * Or custom patterns registered via registerMovement()
237
+ * @param {object} params - Execution parameters (varies by pattern)
238
238
  *
239
- * 사용 예:
239
+ * Usage:
240
240
  * connector.customMove('zigzag', { distance: 200, amplitude: 30 });
241
241
  * connector.customMove('patrol', { pointAX: 100, pointBX: 500, laps: 5 });
242
242
  * connector.customMove('shake', { intensity: 6, duration: 1000 });
@@ -245,39 +245,39 @@ class ClawMateConnector extends EventEmitter {
245
245
  return this._send('custom_move', { name, params });
246
246
  }
247
247
 
248
- /** 현재 실행 중인 커스텀 이동 강제 중지 */
248
+ /** Force stop currently running custom movement */
249
249
  stopCustomMove() {
250
250
  return this._send('stop_custom_move', {});
251
251
  }
252
252
 
253
- /** 등록된 이동 패턴 목록 요청 (응답은 user_event로 수신) */
253
+ /** Request list of registered movement patterns (response via user_event) */
254
254
  listMovements() {
255
255
  return this._send('list_movements', {});
256
256
  }
257
257
 
258
- /** 스마트 파일 조작 명령 전송 */
258
+ /** Send smart file operation command */
259
259
  smartFileOp(payload) {
260
260
  return this._send('smart_file_op', payload);
261
261
  }
262
262
 
263
- /** 캐릭터 데이터 전송 (AI 생성 캐릭터 적용) */
263
+ /** Send character data (apply AI-generated character) */
264
264
  setCharacter(data) {
265
265
  return this._send('set_character', data);
266
266
  }
267
267
 
268
- /** 원래 캐릭터로 리셋 */
268
+ /** Reset to default character */
269
269
  resetCharacter() {
270
270
  return this._send('reset_character', {});
271
271
  }
272
272
 
273
- /** 인격체 전환 (Incarnation 모드에서 인격 반영) */
273
+ /** Switch persona (reflect bot personality in Incarnation mode) */
274
274
  setPersona(data) {
275
275
  return this._send('set_persona', data);
276
276
  }
277
277
 
278
278
  /**
279
- * 현재 상태 요청 (Promise 반환)
280
- * 서버에서 state_response 오면 resolve, 타임아웃 캐시된 상태 반환
279
+ * Request current pet state (returns Promise)
280
+ * Resolves when state_response arrives from server, returns cached state on timeout
281
281
  */
282
282
  queryState(timeout = 2000) {
283
283
  return new Promise((resolve) => {
@@ -297,22 +297,22 @@ class ClawMateConnector extends EventEmitter {
297
297
  });
298
298
  }
299
299
 
300
- /** 화면 캡처 요청 (ClawMate에서 스크린샷 촬영 응답) */
300
+ /** Request screen capture (ClawMate takes screenshot and responds) */
301
301
  requestScreenCapture() {
302
302
  return this._send('query_screen', {});
303
303
  }
304
304
 
305
- /** 화면 캡처 응답 리스너 등록 */
305
+ /** Register screen capture response listener */
306
306
  onScreenCapture(callback) {
307
307
  this.on('screen_capture', callback);
308
308
  }
309
309
 
310
- /** 사용자 이벤트 리스너 등록 */
310
+ /** Register user event listener */
311
311
  onUserEvent(callback) {
312
312
  this.on('user_event', callback);
313
313
  }
314
314
 
315
- /** 메트릭 리포트 리스너 등록 */
315
+ /** Register metrics report listener */
316
316
  onMetrics(callback) {
317
317
  this.on('metrics_report', callback);
318
318
  }