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.
- package/index.js +441 -442
- package/main/ai-bridge.js +59 -59
- package/main/ai-connector.js +60 -60
- package/main/autostart.js +6 -6
- package/main/desktop-path.js +4 -4
- package/main/file-command-parser.js +46 -46
- package/main/file-ops.js +27 -27
- package/main/index.js +17 -17
- package/main/ipc-handlers.js +24 -24
- package/main/manifest.js +2 -2
- package/main/platform.js +16 -16
- package/main/smart-file-ops.js +64 -64
- package/main/store.js +1 -1
- package/main/telegram.js +137 -137
- package/main/tray.js +61 -61
- package/main/updater.js +13 -13
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/preload/preload.js +18 -18
- package/renderer/css/effects.css +6 -6
- package/renderer/css/pet.css +8 -8
- package/renderer/css/speech.css +5 -5
- package/renderer/first-run.html +14 -14
- package/renderer/index.html +4 -4
- package/renderer/js/ai-controller.js +91 -91
- package/renderer/js/app.js +24 -24
- package/renderer/js/browser-watcher.js +32 -32
- package/renderer/js/character.js +33 -33
- package/renderer/js/interactions.js +21 -21
- package/renderer/js/memory.js +60 -60
- package/renderer/js/metrics.js +141 -141
- package/renderer/js/mode-manager.js +13 -13
- package/renderer/js/pet-engine.js +236 -236
- package/renderer/js/speech.js +19 -19
- package/renderer/js/state-machine.js +23 -23
- package/renderer/js/time-aware.js +15 -15
- package/renderer/launcher.html +8 -8
- package/shared/constants.js +11 -11
- package/shared/messages.js +130 -130
- package/shared/personalities.js +44 -44
- package/skills/launch-pet/index.js +57 -47
- package/skills/launch-pet/skill.json +12 -23
package/renderer/js/memory.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* User interaction memory + evolution system
|
|
3
3
|
*
|
|
4
|
-
* -
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
4
|
+
* - Tracks click count, days, milestones
|
|
5
|
+
* - Evolution stage management: always evolves in positive/cute directions only
|
|
6
|
+
* - Never transforms into scary/creepy appearances
|
|
7
7
|
*/
|
|
8
8
|
const Memory = (() => {
|
|
9
9
|
let data = {
|
|
@@ -13,16 +13,16 @@ const Memory = (() => {
|
|
|
13
13
|
lastVisitDate: null,
|
|
14
14
|
milestones: [],
|
|
15
15
|
evolutionStage: 0,
|
|
16
|
-
interactionStreak: 0, //
|
|
16
|
+
interactionStreak: 0, // Consecutive visit days
|
|
17
17
|
|
|
18
|
-
// ---
|
|
19
|
-
motionHistory: [], //
|
|
20
|
-
motionStats: {}, //
|
|
18
|
+
// --- Motion history ---
|
|
19
|
+
motionHistory: [], // Recent 100 state transition records [{state, timestamp, duration}]
|
|
20
|
+
motionStats: {}, // Accumulated time per state {idle: 12345, walking: 6789, ...}
|
|
21
21
|
|
|
22
|
-
// ---
|
|
23
|
-
reactionLog: [], //
|
|
24
|
-
favoriteActions: {}, //
|
|
25
|
-
dislikedActions: {}, //
|
|
22
|
+
// --- User reaction storage ---
|
|
23
|
+
reactionLog: [], // Recent 50 user reactions [{action, reaction, timestamp}]
|
|
24
|
+
favoriteActions: {}, // Positive reaction count per action {excited: 5, walking: 2, ...}
|
|
25
|
+
dislikedActions: {}, // Negative reaction count per action (ignored/abandoned)
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
let lastMotionState = null;
|
|
@@ -40,22 +40,22 @@ const Memory = (() => {
|
|
|
40
40
|
|
|
41
41
|
evolutionStages = window._evolutionStages;
|
|
42
42
|
|
|
43
|
-
//
|
|
43
|
+
// First run
|
|
44
44
|
if (!data.firstRunDate) {
|
|
45
45
|
data.firstRunDate = new Date().toISOString();
|
|
46
46
|
await save();
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
//
|
|
49
|
+
// Calculate days
|
|
50
50
|
updateDayCount();
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// Check milestones
|
|
53
53
|
checkMilestones();
|
|
54
54
|
|
|
55
|
-
//
|
|
55
|
+
// Check evolution
|
|
56
56
|
checkEvolution();
|
|
57
57
|
|
|
58
|
-
//
|
|
58
|
+
// Apply evolution visual effects
|
|
59
59
|
applyEvolutionVisuals();
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -64,7 +64,7 @@ const Memory = (() => {
|
|
|
64
64
|
const now = new Date();
|
|
65
65
|
data.totalDays = Math.floor((now - firstRun) / (1000 * 60 * 60 * 24));
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// Check consecutive visits
|
|
68
68
|
const lastVisit = data.lastVisitDate ? new Date(data.lastVisitDate) : null;
|
|
69
69
|
const today = now.toDateString();
|
|
70
70
|
if (lastVisit && lastVisit.toDateString() !== today) {
|
|
@@ -103,7 +103,7 @@ const Memory = (() => {
|
|
|
103
103
|
data.milestones.push(check.key);
|
|
104
104
|
const msg = Speech.getMilestoneMessage(check.key);
|
|
105
105
|
if (msg) {
|
|
106
|
-
//
|
|
106
|
+
// Display milestone message after a slight delay
|
|
107
107
|
setTimeout(() => {
|
|
108
108
|
Speech.show(msg);
|
|
109
109
|
Interactions.spawnStarEffect();
|
|
@@ -114,9 +114,9 @@ const Memory = (() => {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
117
|
+
* Check evolution stage
|
|
118
|
+
* Only goes up (no devolution)
|
|
119
|
+
* Condition: both click count and days together must be met
|
|
120
120
|
*/
|
|
121
121
|
function checkEvolution() {
|
|
122
122
|
if (!evolutionStages) return;
|
|
@@ -141,22 +141,22 @@ const Memory = (() => {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
|
-
*
|
|
145
|
-
* -
|
|
146
|
-
* -
|
|
147
|
-
* -
|
|
144
|
+
* Evolution event handler
|
|
145
|
+
* - Bright flash effect (soft light)
|
|
146
|
+
* - Sparkle particles
|
|
147
|
+
* - Congratulatory message
|
|
148
148
|
*/
|
|
149
149
|
function onEvolution(prevStage, newStage) {
|
|
150
150
|
const msgs = window._messages;
|
|
151
151
|
const stageInfo = evolutionStages[newStage];
|
|
152
152
|
|
|
153
|
-
//
|
|
153
|
+
// Bright flash (soft, non-scary effect)
|
|
154
154
|
const flash = document.createElement('div');
|
|
155
155
|
flash.className = 'evolve-flash';
|
|
156
156
|
document.body.appendChild(flash);
|
|
157
157
|
setTimeout(() => flash.remove(), 600);
|
|
158
158
|
|
|
159
|
-
//
|
|
159
|
+
// Evolution sparkle particles (bright colors only)
|
|
160
160
|
const pos = PetEngine.getPosition();
|
|
161
161
|
const sparkleColors = ['#FFD700', '#FF69B4', '#87CEEB', '#98FB98', '#DDA0DD'];
|
|
162
162
|
for (let i = 0; i < 16; i++) {
|
|
@@ -169,7 +169,7 @@ const Memory = (() => {
|
|
|
169
169
|
setTimeout(() => sparkle.remove(), 800);
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
//
|
|
172
|
+
// Evolution ring effect (warm colors)
|
|
173
173
|
const ring = document.createElement('div');
|
|
174
174
|
ring.className = 'evolve-ring';
|
|
175
175
|
ring.style.width = '64px';
|
|
@@ -180,7 +180,7 @@ const Memory = (() => {
|
|
|
180
180
|
document.getElementById('world').appendChild(ring);
|
|
181
181
|
setTimeout(() => ring.remove(), 1000);
|
|
182
182
|
|
|
183
|
-
//
|
|
183
|
+
// Congratulatory message
|
|
184
184
|
if (msgs && msgs.evolution) {
|
|
185
185
|
const evolveMsg = msgs.evolution[`stage_${newStage}`];
|
|
186
186
|
if (evolveMsg) {
|
|
@@ -188,13 +188,13 @@ const Memory = (() => {
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
//
|
|
191
|
+
// Update visual effects
|
|
192
192
|
applyEvolutionVisuals();
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
196
|
+
* Apply visual changes based on evolution stage
|
|
197
|
+
* Always positive: gets brighter, sparkly, and cute accessories added
|
|
198
198
|
*/
|
|
199
199
|
function applyEvolutionVisuals() {
|
|
200
200
|
if (!evolutionStages) return;
|
|
@@ -204,17 +204,17 @@ const Memory = (() => {
|
|
|
204
204
|
const pet = document.getElementById('pet-container');
|
|
205
205
|
if (!pet) return;
|
|
206
206
|
|
|
207
|
-
//
|
|
207
|
+
// Size scale
|
|
208
208
|
pet.style.transform = pet.style.transform || '';
|
|
209
209
|
|
|
210
|
-
//
|
|
210
|
+
// Brightness/saturation -- gets brighter and more vibrant with evolution
|
|
211
211
|
const { brightness, saturation } = stage.colorMod;
|
|
212
212
|
const canvas = pet.querySelector('canvas');
|
|
213
213
|
if (canvas) {
|
|
214
214
|
canvas.style.filter = `brightness(${brightness}) saturate(${saturation})`;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
//
|
|
217
|
+
// Remove accessories then reapply
|
|
218
218
|
pet.querySelectorAll('.accessory').forEach(a => a.remove());
|
|
219
219
|
|
|
220
220
|
for (const acc of stage.accessories) {
|
|
@@ -223,8 +223,8 @@ const Memory = (() => {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
226
|
+
* Add cute accessories
|
|
227
|
+
* All accessories are bright and cute elements only
|
|
228
228
|
*/
|
|
229
229
|
function addAccessory(container, type) {
|
|
230
230
|
const acc = document.createElement('div');
|
|
@@ -235,7 +235,7 @@ const Memory = (() => {
|
|
|
235
235
|
|
|
236
236
|
switch (type) {
|
|
237
237
|
case 'blush':
|
|
238
|
-
//
|
|
238
|
+
// Pink circles on both cheeks
|
|
239
239
|
acc.style.width = '8px';
|
|
240
240
|
acc.style.height = '6px';
|
|
241
241
|
acc.style.borderRadius = '50%';
|
|
@@ -243,14 +243,14 @@ const Memory = (() => {
|
|
|
243
243
|
acc.style.left = '12px';
|
|
244
244
|
acc.style.top = '38px';
|
|
245
245
|
container.appendChild(acc);
|
|
246
|
-
//
|
|
246
|
+
// Right cheek
|
|
247
247
|
const blush2 = acc.cloneNode();
|
|
248
248
|
blush2.style.left = '44px';
|
|
249
249
|
container.appendChild(blush2);
|
|
250
250
|
return;
|
|
251
251
|
|
|
252
252
|
case 'sparkle_eyes':
|
|
253
|
-
//
|
|
253
|
+
// Eye sparkles (small white dots)
|
|
254
254
|
acc.style.width = '3px';
|
|
255
255
|
acc.style.height = '3px';
|
|
256
256
|
acc.style.borderRadius = '50%';
|
|
@@ -300,14 +300,14 @@ const Memory = (() => {
|
|
|
300
300
|
break;
|
|
301
301
|
|
|
302
302
|
case 'wings':
|
|
303
|
-
//
|
|
303
|
+
// Small angel wings (left)
|
|
304
304
|
acc.textContent = '\u{1FABD}';
|
|
305
305
|
acc.style.fontSize = '10px';
|
|
306
306
|
acc.style.left = '-6px';
|
|
307
307
|
acc.style.top = '20px';
|
|
308
308
|
acc.style.opacity = '0.7';
|
|
309
309
|
container.appendChild(acc);
|
|
310
|
-
//
|
|
310
|
+
// Right wing
|
|
311
311
|
const wing2 = acc.cloneNode(true);
|
|
312
312
|
wing2.style.left = '58px';
|
|
313
313
|
wing2.style.transform = 'scaleX(-1)';
|
|
@@ -318,30 +318,30 @@ const Memory = (() => {
|
|
|
318
318
|
container.appendChild(acc);
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
// ---
|
|
321
|
+
// --- Motion history recording ---
|
|
322
322
|
|
|
323
323
|
/**
|
|
324
|
-
*
|
|
325
|
-
*
|
|
324
|
+
* Record state transition
|
|
325
|
+
* Called when state changes in StateMachine
|
|
326
326
|
*/
|
|
327
327
|
function recordMotion(newState) {
|
|
328
328
|
const now = Date.now();
|
|
329
329
|
|
|
330
|
-
//
|
|
330
|
+
// Calculate previous state duration -> accumulate statistics
|
|
331
331
|
if (lastMotionState && lastMotionTime > 0) {
|
|
332
332
|
const duration = now - lastMotionTime;
|
|
333
333
|
if (!data.motionStats[lastMotionState]) data.motionStats[lastMotionState] = 0;
|
|
334
334
|
data.motionStats[lastMotionState] += duration;
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
//
|
|
337
|
+
// Add to history
|
|
338
338
|
data.motionHistory.push({
|
|
339
339
|
state: newState,
|
|
340
340
|
timestamp: now,
|
|
341
341
|
from: lastMotionState || 'init',
|
|
342
342
|
});
|
|
343
343
|
|
|
344
|
-
//
|
|
344
|
+
// Remove old entries when exceeding max size
|
|
345
345
|
if (data.motionHistory.length > MAX_MOTION_HISTORY) {
|
|
346
346
|
data.motionHistory = data.motionHistory.slice(-MAX_MOTION_HISTORY);
|
|
347
347
|
}
|
|
@@ -349,32 +349,32 @@ const Memory = (() => {
|
|
|
349
349
|
lastMotionState = newState;
|
|
350
350
|
lastMotionTime = now;
|
|
351
351
|
|
|
352
|
-
//
|
|
352
|
+
// Auto-save every 10 transitions
|
|
353
353
|
if (data.motionHistory.length % 10 === 0) save();
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
/**
|
|
357
|
-
*
|
|
358
|
-
*
|
|
357
|
+
* Record user reaction
|
|
358
|
+
* When user shows reactions like click/drag during a specific action
|
|
359
359
|
*
|
|
360
|
-
* @param {string} action -
|
|
360
|
+
* @param {string} action - Action the pet was performing
|
|
361
361
|
* @param {string} reaction - 'click' | 'drag' | 'cursor_near' | 'triple_click' | 'double_click'
|
|
362
362
|
*/
|
|
363
363
|
function recordReaction(action, reaction) {
|
|
364
364
|
const now = Date.now();
|
|
365
365
|
|
|
366
|
-
//
|
|
366
|
+
// Add to reaction log
|
|
367
367
|
data.reactionLog.push({ action, reaction, timestamp: now });
|
|
368
368
|
if (data.reactionLog.length > MAX_REACTION_LOG) {
|
|
369
369
|
data.reactionLog = data.reactionLog.slice(-MAX_REACTION_LOG);
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
//
|
|
372
|
+
// Click/double-click classified as positive reactions
|
|
373
373
|
if (reaction === 'click' || reaction === 'double_click' || reaction === 'cursor_near') {
|
|
374
374
|
if (!data.favoriteActions[action]) data.favoriteActions[action] = 0;
|
|
375
375
|
data.favoriteActions[action]++;
|
|
376
376
|
}
|
|
377
|
-
//
|
|
377
|
+
// Drag (grab and move) is a slightly negative reaction
|
|
378
378
|
if (reaction === 'drag') {
|
|
379
379
|
if (!data.dislikedActions[action]) data.dislikedActions[action] = 0;
|
|
380
380
|
data.dislikedActions[action]++;
|
|
@@ -384,8 +384,8 @@ const Memory = (() => {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
/**
|
|
387
|
-
*
|
|
388
|
-
* AI
|
|
387
|
+
* Return top N user-preferred actions
|
|
388
|
+
* Referenced by AI when deciding actions
|
|
389
389
|
*/
|
|
390
390
|
function getFavoriteActions(topN = 5) {
|
|
391
391
|
const entries = Object.entries(data.favoriteActions || {});
|
|
@@ -394,14 +394,14 @@ const Memory = (() => {
|
|
|
394
394
|
}
|
|
395
395
|
|
|
396
396
|
/**
|
|
397
|
-
*
|
|
397
|
+
* Return recent motion history
|
|
398
398
|
*/
|
|
399
399
|
function getMotionHistory(limit = 20) {
|
|
400
400
|
return (data.motionHistory || []).slice(-limit);
|
|
401
401
|
}
|
|
402
402
|
|
|
403
403
|
/**
|
|
404
|
-
*
|
|
404
|
+
* Return accumulated time per state
|
|
405
405
|
*/
|
|
406
406
|
function getMotionStats() {
|
|
407
407
|
return { ...(data.motionStats || {}) };
|