clawd-desktop 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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/assets/LICENSE-clawd +22 -0
  4. package/assets/gif/clawd-building.gif +0 -0
  5. package/assets/gif/clawd-carrying.gif +0 -0
  6. package/assets/gif/clawd-conducting.gif +0 -0
  7. package/assets/gif/clawd-debugger.gif +0 -0
  8. package/assets/gif/clawd-error.gif +0 -0
  9. package/assets/gif/clawd-happy.gif +0 -0
  10. package/assets/gif/clawd-idle-reading.gif +0 -0
  11. package/assets/gif/clawd-idle.gif +0 -0
  12. package/assets/gif/clawd-juggling.gif +0 -0
  13. package/assets/gif/clawd-notification.gif +0 -0
  14. package/assets/gif/clawd-react-annoyed.gif +0 -0
  15. package/assets/gif/clawd-react-double-jump.gif +0 -0
  16. package/assets/gif/clawd-sleeping.gif +0 -0
  17. package/assets/gif/clawd-sweeping.gif +0 -0
  18. package/assets/gif/clawd-thinking.gif +0 -0
  19. package/assets/gif/clawd-typing.gif +0 -0
  20. package/assets/svg/clawd-about-hero.svg +202 -0
  21. package/assets/svg/clawd-collapse-sleep.svg +247 -0
  22. package/assets/svg/clawd-error.svg +94 -0
  23. package/assets/svg/clawd-happy.svg +161 -0
  24. package/assets/svg/clawd-idle-collapse.svg +101 -0
  25. package/assets/svg/clawd-idle-doze.svg +72 -0
  26. package/assets/svg/clawd-idle-follow.svg +64 -0
  27. package/assets/svg/clawd-idle-living.svg +196 -0
  28. package/assets/svg/clawd-idle-look.svg +115 -0
  29. package/assets/svg/clawd-idle-reading.svg +201 -0
  30. package/assets/svg/clawd-idle-yawn.svg +158 -0
  31. package/assets/svg/clawd-mini-alert.svg +129 -0
  32. package/assets/svg/clawd-mini-crabwalk.svg +76 -0
  33. package/assets/svg/clawd-mini-enter-sleep.svg +65 -0
  34. package/assets/svg/clawd-mini-enter.svg +115 -0
  35. package/assets/svg/clawd-mini-happy.svg +124 -0
  36. package/assets/svg/clawd-mini-idle.svg +83 -0
  37. package/assets/svg/clawd-mini-peek.svg +82 -0
  38. package/assets/svg/clawd-mini-sleep.svg +112 -0
  39. package/assets/svg/clawd-mini-typing.svg +153 -0
  40. package/assets/svg/clawd-notification.svg +149 -0
  41. package/assets/svg/clawd-react-annoyed.svg +167 -0
  42. package/assets/svg/clawd-react-double-jump.svg +229 -0
  43. package/assets/svg/clawd-react-double.svg +108 -0
  44. package/assets/svg/clawd-react-drag.svg +102 -0
  45. package/assets/svg/clawd-react-left.svg +102 -0
  46. package/assets/svg/clawd-react-right.svg +102 -0
  47. package/assets/svg/clawd-sleeping.svg +118 -0
  48. package/assets/svg/clawd-static-base.svg +21 -0
  49. package/assets/svg/clawd-wake.svg +277 -0
  50. package/assets/svg/clawd-working-building.svg +329 -0
  51. package/assets/svg/clawd-working-carrying.svg +178 -0
  52. package/assets/svg/clawd-working-conducting.svg +220 -0
  53. package/assets/svg/clawd-working-debugger.svg +245 -0
  54. package/assets/svg/clawd-working-juggling.svg +183 -0
  55. package/assets/svg/clawd-working-sweeping.svg +248 -0
  56. package/assets/svg/clawd-working-thinking.svg +196 -0
  57. package/assets/svg/clawd-working-typing.svg +273 -0
  58. package/assets/svg/clawd-working-ultrathink.svg +166 -0
  59. package/assets/svg/clawd-working-wizard.svg +98 -0
  60. package/assets/tray-icon.ico +0 -0
  61. package/bin/claude-pet.js +6 -0
  62. package/main.js +86 -0
  63. package/package.json +38 -0
  64. package/preload.js +6 -0
  65. package/renderer/avatar.js +55 -0
  66. package/renderer/index.html +14 -0
  67. package/renderer/motion.js +24 -0
  68. package/renderer/style.css +104 -0
@@ -0,0 +1,273 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ /* ===== Body (KEEP) ===== */
5
+ .body-bounce {
6
+ transform-origin: 7.5px 15px;
7
+ animation: body-bounce 0.35s infinite ease-in-out;
8
+ }
9
+ .breathe {
10
+ transform-origin: 7.5px 13px;
11
+ animation: breathe 3.2s infinite ease-in-out;
12
+ }
13
+
14
+ /* ===== Arms (KEEP) ===== */
15
+ .arm-l-type {
16
+ transform-origin: 2px 10px;
17
+ animation: type-l 0.15s infinite ease-in-out;
18
+ }
19
+ .arm-r-type {
20
+ transform-origin: 13px 10px;
21
+ animation: type-r 0.12s infinite ease-in-out;
22
+ }
23
+
24
+ /* ===== Eyes ===== */
25
+ .eyes-code {
26
+ transform-origin: 7.5px 9px;
27
+ animation: eye-code 10s infinite ease-in-out;
28
+ }
29
+
30
+ /* ===== Code lines: each line grows, holds, then slides up + fades ===== */
31
+ .code-line {
32
+ transform-box: fill-box;
33
+ transform-origin: left center;
34
+ }
35
+ .cl1 { animation: cl1 6s infinite; }
36
+ .cl2 { animation: cl2 6s infinite; }
37
+ .cl3 { animation: cl3 6s infinite; }
38
+ .cl4 { animation: cl4 6s infinite; }
39
+
40
+ /* Key press flashes — different periods so they look random */
41
+ .key-flash { opacity: 0; }
42
+ .kf1 { animation: kflash 0.6s infinite; }
43
+ .kf2 { animation: kflash 0.8s infinite; animation-delay: -0.25s; }
44
+ .kf3 { animation: kflash 0.5s infinite; animation-delay: -0.1s; }
45
+ .kf4 { animation: kflash 0.7s infinite; animation-delay: -0.45s; }
46
+ .kf5 { animation: kflash 0.55s infinite; animation-delay: -0.3s; }
47
+ .kf6 { animation: kflash 0.9s infinite; animation-delay: -0.5s; }
48
+
49
+ /* Data particles (float up behind screen) */
50
+ .data-bit { opacity: 0; animation: float-data 1.5s infinite linear; }
51
+ .d1 { animation-delay: 0s; }
52
+ .d2 { animation-delay: -0.4s; }
53
+ .d3 { animation-delay: -0.8s; }
54
+ .d4 { animation-delay: -1.2s; }
55
+
56
+ /* Shadow */
57
+ .shadow-anim {
58
+ transform-origin: 7.5px 15.5px;
59
+ animation: shadow-bob 0.4s infinite ease-in-out;
60
+ }
61
+
62
+ /* ==================== Keyframes ==================== */
63
+
64
+ @keyframes body-bounce {
65
+ 0%, 100% { transform: translateY(0); }
66
+ 50% { transform: translateY(0.8px); }
67
+ }
68
+ @keyframes breathe {
69
+ 0%, 100% { transform: scale(1, 1) translate(0, 0); }
70
+ 50% { transform: scale(1.02, 0.98) translate(0, 0.5px); }
71
+ }
72
+ @keyframes shadow-bob {
73
+ 0%, 100% { transform: scaleX(1.02); opacity: 0.5; }
74
+ 50% { transform: scaleX(1.05); opacity: 0.55; }
75
+ }
76
+
77
+ @keyframes type-l {
78
+ 0% { transform: rotate(-5deg); }
79
+ 25% { transform: rotate(-38deg); }
80
+ 50% { transform: rotate(-10deg); }
81
+ 75% { transform: rotate(-30deg); }
82
+ 100% { transform: rotate(-5deg); }
83
+ }
84
+ @keyframes type-r {
85
+ 0% { transform: rotate(5deg); }
86
+ 25% { transform: rotate(38deg); }
87
+ 50% { transform: rotate(10deg); }
88
+ 75% { transform: rotate(30deg); }
89
+ 100% { transform: rotate(5deg); }
90
+ }
91
+
92
+ /* Eyes: long keyboard squint → 2 consecutive scans → keyboard */
93
+ @keyframes eye-code {
94
+ 0% { transform: translate(0, 1px) scaleY(0.6); }
95
+ 14% { transform: translate(0, 1px) scaleY(0.6); }
96
+ 15% { transform: translate(0, 1px) scaleY(0.1); }
97
+ 16% { transform: translate(0, 1px) scaleY(0.6); }
98
+ 36% { transform: translate(0, 1px) scaleY(0.6); }
99
+ 37% { transform: translate(0, 1px) scaleY(0.1); }
100
+ 38% { transform: translate(0, 1px) scaleY(0.6); }
101
+ 54% { transform: translate(0, 1px) scaleY(0.6); }
102
+ 55% { transform: translate(0, 1px) scaleY(0.1); }
103
+ 57% { transform: translate(-1px, -0.5px) scaleY(1); }
104
+ 62% { transform: translate(1.5px, -0.5px) scaleY(1); }
105
+ 64% { transform: translate(-0.5px, -0.3px) scaleY(1); }
106
+ 69% { transform: translate(1.5px, -0.5px) scaleY(1); }
107
+ 71% { transform: translate(1px, -0.3px) scaleY(0.1); }
108
+ 73% { transform: translate(0, 1px) scaleY(0.6); }
109
+ 89% { transform: translate(0, 1px) scaleY(0.6); }
110
+ 90% { transform: translate(0, 1px) scaleY(0.1); }
111
+ 91% { transform: translate(0, 1px) scaleY(0.6); }
112
+ 100% { transform: translate(0, 1px) scaleY(0.6); }
113
+ }
114
+
115
+ /* Code lines: grow from left → hold → slide up + fade out
116
+ Each line staggers by ~15%. Slide-up gives "scroll" feel.
117
+ At 95-100% all invisible → brief blank → cycle restarts */
118
+ @keyframes cl1 {
119
+ 0% { transform: scaleX(0); opacity: 0; }
120
+ 3% { transform: scaleX(0); opacity: 1; }
121
+ 13% { transform: scaleX(1); opacity: 1; }
122
+ 13%, 78% { transform: scaleX(1) translateY(0); opacity: 1; }
123
+ 88% { transform: scaleX(1) translateY(-3px); opacity: 0; }
124
+ 89%, 100% { transform: scaleX(0) translateY(0); opacity: 0; }
125
+ }
126
+ @keyframes cl2 {
127
+ 0%, 14% { transform: scaleX(0); opacity: 0; }
128
+ 15% { transform: scaleX(0); opacity: 1; }
129
+ 27% { transform: scaleX(1); opacity: 1; }
130
+ 27%, 82% { transform: scaleX(1) translateY(0); opacity: 1; }
131
+ 91% { transform: scaleX(1) translateY(-3px); opacity: 0; }
132
+ 92%, 100% { transform: scaleX(0) translateY(0); opacity: 0; }
133
+ }
134
+ @keyframes cl3 {
135
+ 0%, 29% { transform: scaleX(0); opacity: 0; }
136
+ 30% { transform: scaleX(0); opacity: 1; }
137
+ 42% { transform: scaleX(1); opacity: 1; }
138
+ 42%, 85% { transform: scaleX(1) translateY(0); opacity: 1; }
139
+ 93% { transform: scaleX(1) translateY(-3px); opacity: 0; }
140
+ 94%, 100% { transform: scaleX(0) translateY(0); opacity: 0; }
141
+ }
142
+ @keyframes cl4 {
143
+ 0%, 44% { transform: scaleX(0); opacity: 0; }
144
+ 45% { transform: scaleX(0); opacity: 1; }
145
+ 57% { transform: scaleX(1); opacity: 1; }
146
+ 57%, 88% { transform: scaleX(1) translateY(0); opacity: 1; }
147
+ 95% { transform: scaleX(1) translateY(-3px); opacity: 0; }
148
+ 96%, 100% { transform: scaleX(0) translateY(0); opacity: 0; }
149
+ }
150
+
151
+ /* Key flash: brief bright pulse, mostly off */
152
+ @keyframes kflash {
153
+ 0%, 70%, 100% { opacity: 0; }
154
+ 35% { opacity: 0.8; }
155
+ }
156
+
157
+ @keyframes float-data {
158
+ 0% { transform: translateY(0) scale(0.5); opacity: 0; }
159
+ 10% { opacity: 0.8; }
160
+ 100% { transform: translateY(-17px) scale(1); opacity: 0; }
161
+ }
162
+ </style>
163
+ <g id="pixel-packet">
164
+ <rect x="0" y="0" width="1.5" height="1.5"/>
165
+ </g>
166
+ </defs>
167
+
168
+ <!-- Ground Shadow -->
169
+ <rect class="shadow-anim" x="3" y="15" width="9" height="1" fill="#000" opacity="0.5"/>
170
+
171
+ <!-- Data particles (behind screen, float up and disappear behind it) -->
172
+ <g fill="#40C4FF">
173
+ <use href="#pixel-packet" class="data-bit d1" x="3" y="7"/>
174
+ <use href="#pixel-packet" class="data-bit d2" x="7" y="8"/>
175
+ <use href="#pixel-packet" class="data-bit d3" x="11" y="7"/>
176
+ <use href="#pixel-packet" class="data-bit d4" x="5" y="8"/>
177
+ </g>
178
+
179
+ <!-- Mini Screen -->
180
+ <g id="screen" transform="translate(1.25, 0)">
181
+ <rect x="-0.5" y="-6" width="13.5" height="10.5" fill="#1E1E2E" rx="0.3"/>
182
+ <rect x="-0.5" y="-6" width="13.5" height="1.2" fill="#2D2D3D" rx="0.3"/>
183
+ <rect x="0.3" y="-5.6" width="0.5" height="0.4" fill="#FF5F56"/>
184
+ <rect x="1.2" y="-5.6" width="0.5" height="0.4" fill="#FFBD2E"/>
185
+ <rect x="2.1" y="-5.6" width="0.5" height="0.4" fill="#27C93F"/>
186
+
187
+ <!-- Code lines (indented, varying lengths = code structure) -->
188
+ <rect class="code-line cl1" x="0.5" y="-3.5" width="5" height="0.7" fill="#4CAF50" opacity="0.8"/>
189
+ <rect class="code-line cl2" x="2" y="-1.8" width="8" height="0.7" fill="#4CAF50" opacity="0.8"/>
190
+ <rect class="code-line cl3" x="2" y="-0.1" width="4.5" height="0.7" fill="#40C4FF" opacity="0.7"/>
191
+ <rect class="code-line cl4" x="0.5" y="1.6" width="2" height="0.7" fill="#FFC107" opacity="0.7"/>
192
+
193
+ </g>
194
+
195
+ <!-- Layer 1: Body -->
196
+ <g class="body-bounce">
197
+ <g class="breathe">
198
+ <g fill="#DE886D">
199
+ <rect x="3" y="13" width="1" height="2"/>
200
+ <rect x="5" y="13" width="1" height="2"/>
201
+ <rect x="9" y="13" width="1" height="2"/>
202
+ <rect x="11" y="13" width="1" height="2"/>
203
+ <rect x="2" y="6" width="11" height="7"/>
204
+ </g>
205
+ <g class="eyes-code" fill="#000">
206
+ <rect x="4" y="8" width="1" height="2"/>
207
+ <rect x="10" y="8" width="1" height="2"/>
208
+ </g>
209
+ </g>
210
+ </g>
211
+
212
+ <!-- Layer 2: Keyboard -->
213
+ <g id="keyboard" transform="translate(-0.5, 11.8)">
214
+ <rect x="0" y="0" width="16" height="3.2" fill="#455A64" rx="0.3"/>
215
+ <g fill="#78909C">
216
+ <rect x="0.5" y="0.4" width="1" height="0.7"/>
217
+ <rect x="1.8" y="0.4" width="1" height="0.7"/>
218
+ <rect x="3.5" y="0.4" width="6" height="0.7" rx="0.2"/>
219
+ <rect x="10.2" y="0.4" width="1" height="0.7"/>
220
+ <rect x="11.5" y="0.4" width="1" height="0.7"/>
221
+ <rect x="12.8" y="0.4" width="1" height="0.7"/>
222
+ <rect x="14.1" y="0.4" width="1.3" height="0.7"/>
223
+ </g>
224
+ <g fill="#78909C">
225
+ <rect x="0.8" y="1.3" width="0.9" height="0.7"/>
226
+ <rect x="2.0" y="1.3" width="0.9" height="0.7"/>
227
+ <rect x="3.2" y="1.3" width="0.9" height="0.7"/>
228
+ <rect x="4.4" y="1.3" width="0.9" height="0.7"/>
229
+ <rect x="5.6" y="1.3" width="0.9" height="0.7"/>
230
+ <rect x="6.8" y="1.3" width="0.9" height="0.7"/>
231
+ <rect x="8.0" y="1.3" width="0.9" height="0.7"/>
232
+ <rect x="9.2" y="1.3" width="0.9" height="0.7"/>
233
+ <rect x="10.4" y="1.3" width="0.9" height="0.7"/>
234
+ <rect x="11.6" y="1.3" width="0.9" height="0.7"/>
235
+ <rect x="12.8" y="1.3" width="0.9" height="0.7"/>
236
+ <rect x="14.0" y="1.3" width="0.9" height="0.7"/>
237
+ </g>
238
+ <g fill="#78909C">
239
+ <rect x="0.5" y="2.2" width="0.9" height="0.7"/>
240
+ <rect x="1.7" y="2.2" width="0.9" height="0.7"/>
241
+ <rect x="2.9" y="2.2" width="0.9" height="0.7"/>
242
+ <rect x="4.1" y="2.2" width="0.9" height="0.7"/>
243
+ <rect x="5.3" y="2.2" width="0.9" height="0.7"/>
244
+ <rect x="6.5" y="2.2" width="0.9" height="0.7"/>
245
+ <rect x="7.7" y="2.2" width="0.9" height="0.7"/>
246
+ <rect x="8.9" y="2.2" width="0.9" height="0.7"/>
247
+ <rect x="10.1" y="2.2" width="0.9" height="0.7"/>
248
+ <rect x="11.3" y="2.2" width="0.9" height="0.7"/>
249
+ <rect x="12.5" y="2.2" width="0.9" height="0.7"/>
250
+ <rect x="13.7" y="2.2" width="0.9" height="0.7"/>
251
+ <rect x="14.9" y="2.2" width="0.6" height="0.7"/>
252
+ </g>
253
+ <!-- Key press highlights (overlay on top of keys) -->
254
+ <g fill="#B0BEC5">
255
+ <rect class="key-flash kf1" x="4.4" y="1.3" width="0.9" height="0.7"/>
256
+ <rect class="key-flash kf2" x="9.2" y="1.3" width="0.9" height="0.7"/>
257
+ <rect class="key-flash kf3" x="2.9" y="2.2" width="0.9" height="0.7"/>
258
+ <rect class="key-flash kf4" x="7.7" y="2.2" width="0.9" height="0.7"/>
259
+ <rect class="key-flash kf5" x="11.6" y="1.3" width="0.9" height="0.7"/>
260
+ <rect class="key-flash kf6" x="3.5" y="0.4" width="6" height="0.7" rx="0.2"/>
261
+ </g>
262
+ </g>
263
+
264
+ <!-- Layer 3: Arms -->
265
+ <g class="body-bounce">
266
+ <g class="breathe">
267
+ <g fill="#DE886D">
268
+ <g class="arm-l-type"><rect x="0" y="9" width="2" height="2"/></g>
269
+ <g class="arm-r-type"><rect x="13" y="9" width="2" height="2"/></g>
270
+ </g>
271
+ </g>
272
+ </g>
273
+ </svg>
@@ -0,0 +1,166 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ /* Intense body trembling */
5
+ .body-shake {
6
+ transform-origin: 7.5px 15px;
7
+ animation: shake 0.15s infinite alternate ease-in-out;
8
+ }
9
+
10
+ /* Shadow vibration */
11
+ .shadow-shake {
12
+ transform-origin: 7.5px 15.5px;
13
+ animation: shadow-vib 0.15s infinite alternate ease-in-out;
14
+ }
15
+
16
+ /* Right arm tapping chin fast */
17
+ .arm-tap-fast {
18
+ transform-origin: 14px 10px;
19
+ animation: tap-fast 0.8s infinite ease-in-out;
20
+ }
21
+
22
+ /* Concentrated squint blink */
23
+ .eyes-focus {
24
+ transform-origin: 7.5px 9px;
25
+ animation: focus-blink 2s infinite;
26
+ }
27
+
28
+ /* Brain sparks rising from head */
29
+ .spark {
30
+ opacity: 0;
31
+ animation: spark-rise 1.2s infinite ease-out;
32
+ }
33
+ .sp1 { animation-delay: 0s; }
34
+ .sp2 { animation-delay: 0.3s; }
35
+ .sp3 { animation-delay: 0.6s; }
36
+ .sp4 { animation-delay: 0.9s; }
37
+
38
+ /* Loading dots spinning */
39
+ .load-dot {
40
+ opacity: 0;
41
+ animation: dot-pulse 1.6s infinite;
42
+ }
43
+ .d1 { animation-delay: 0s; }
44
+ .d2 { animation-delay: 0.4s; }
45
+ .d3 { animation-delay: 0.8s; }
46
+
47
+ /* Steam puffs */
48
+ .steam {
49
+ opacity: 0;
50
+ animation: steam-rise 2s infinite ease-out;
51
+ }
52
+ .st1 { animation-delay: 0s; }
53
+ .st2 { animation-delay: 0.7s; }
54
+ .st3 { animation-delay: 1.4s; }
55
+
56
+ /* Ultrathink letters individual pulse */
57
+ .ul { animation: text-pulse 1s infinite ease-in-out; }
58
+ .ul0 { animation-delay: 0s; }
59
+ .ul1 { animation-delay: 0.1s; }
60
+ .ul2 { animation-delay: 0.2s; }
61
+ .ul3 { animation-delay: 0.3s; }
62
+ .ul4 { animation-delay: 0.4s; }
63
+ .ul5 { animation-delay: 0.5s; }
64
+ .ul6 { animation-delay: 0.6s; }
65
+ .ul7 { animation-delay: 0.7s; }
66
+ .ul8 { animation-delay: 0.8s; }
67
+ .ul9 { animation-delay: 0.9s; }
68
+
69
+ @keyframes text-pulse {
70
+ 0%, 100% { opacity: 0.15; }
71
+ 50% { opacity: 1; }
72
+ }
73
+
74
+ @keyframes shake {
75
+ 0% { transform: translate(-0.3px, 0) rotate(-0.5deg); }
76
+ 100% { transform: translate(0.3px, 0) rotate(0.5deg); }
77
+ }
78
+
79
+ @keyframes shadow-vib {
80
+ 0% { transform: scaleX(0.98); }
81
+ 100% { transform: scaleX(1.02); }
82
+ }
83
+
84
+ @keyframes tap-fast {
85
+ 0%, 100% { transform: rotate(-125deg); }
86
+ 50% { transform: rotate(-145deg); }
87
+ }
88
+
89
+ @keyframes focus-blink {
90
+ 0%, 70%, 78%, 100% { transform: scaleY(1); }
91
+ 74% { transform: scaleY(0.1); }
92
+ }
93
+
94
+ @keyframes spark-rise {
95
+ 0% { transform: translate(0, 0) scale(1); opacity: 0; }
96
+ 15% { opacity: 1; }
97
+ 100% { transform: translate(2px, -12px) scale(0.3); opacity: 0; }
98
+ }
99
+
100
+ @keyframes dot-pulse {
101
+ 0%, 100% { opacity: 0.2; }
102
+ 25%, 75% { opacity: 1; }
103
+ }
104
+
105
+ @keyframes steam-rise {
106
+ 0% { transform: translate(0, 0) scale(0.8); opacity: 0; }
107
+ 20% { opacity: 0.6; }
108
+ 100% { transform: translate(-2px, -10px) scale(1.5); opacity: 0; }
109
+ }
110
+ </style>
111
+ </defs>
112
+
113
+ <!-- Ground Shadow -->
114
+ <rect class="shadow-shake" x="3" y="15" width="9" height="1" fill="#000000" opacity="0.5"/>
115
+
116
+ <!-- Brain Sparks (mirrored x positions around center 7.5) -->
117
+ <g fill="#FFD700">
118
+ <rect class="spark sp1" x="10" y="2" width="1" height="1"/>
119
+ <rect class="spark sp2" x="6" y="0" width="1" height="1"/>
120
+ <rect class="spark sp3" x="3" y="1" width="1" height="1"/>
121
+ <rect class="spark sp4" x="8" y="-1" width="1" height="1"/>
122
+ </g>
123
+
124
+ <!-- Steam Puffs -->
125
+ <g fill="#AAAAAA" opacity="0.5">
126
+ <g class="steam st1"><rect x="5" y="3" width="2" height="1" rx="0.5"/><rect x="4" y="2" width="1" height="1" rx="0.5"/></g>
127
+ <g class="steam st2"><rect x="9" y="2" width="2" height="1" rx="0.5"/><rect x="10" y="1" width="1" height="1" rx="0.5"/></g>
128
+ <g class="steam st3"><rect x="7" y="3" width="1" height="1" rx="0.5"/><rect x="6" y="2" width="2" height="1" rx="0.5"/></g>
129
+ </g>
130
+
131
+ <!-- Loading Dots above head -->
132
+ <g fill="#FF6B35">
133
+ <rect class="load-dot d1" x="4" y="4" width="1" height="1"/>
134
+ <rect class="load-dot d2" x="7" y="4" width="1" height="1"/>
135
+ <rect class="load-dot d3" x="10" y="4" width="1" height="1"/>
136
+ </g>
137
+
138
+ <!-- Mirrored: body + legs only -->
139
+ <g transform="translate(15, 0) scale(-1, 1)">
140
+ <g id="legs" fill="#DE886D">
141
+ <rect x="3" y="13" width="1" height="2"/>
142
+ <rect x="5" y="13" width="1" height="2"/>
143
+ <rect x="9" y="13" width="1" height="2"/>
144
+ <rect x="11" y="13" width="1" height="2"/>
145
+ </g>
146
+
147
+ <g class="body-shake">
148
+ <g fill="#DE886D">
149
+ <rect x="2" y="6" width="11" height="7"/>
150
+ <rect x="0" y="9" width="3" height="2" transform="rotate(25 1 10)"/>
151
+ <g class="arm-tap-fast">
152
+ <rect x="13" y="9" width="2" height="2"/>
153
+ </g>
154
+ </g>
155
+ <g class="eyes-focus" fill="#000000">
156
+ <rect x="5" y="7" width="1" height="2"/>
157
+ <rect x="11" y="7" width="1" height="2"/>
158
+ </g>
159
+ </g>
160
+ </g>
161
+
162
+ <!-- Ultrathink rainbow text (top layer, each letter pulses independently) -->
163
+ <text x="7.5" y="0" text-anchor="middle" font-family="'Söhne', 'Helvetica Neue', Arial, sans-serif" font-size="3.2" font-weight="600" letter-spacing="0.2">
164
+ <tspan class="ul ul0" fill="#FF5252">u</tspan><tspan class="ul ul1" fill="#FF9800">l</tspan><tspan class="ul ul2" fill="#FFC107">t</tspan><tspan class="ul ul3" fill="#4CAF50">r</tspan><tspan class="ul ul4" fill="#2196F3">a</tspan><tspan class="ul ul5" fill="#9C27B0">t</tspan><tspan class="ul ul6" fill="#FF5252">h</tspan><tspan class="ul ul7" fill="#FF9800">i</tspan><tspan class="ul ul8" fill="#4CAF50">n</tspan><tspan class="ul ul9" fill="#2196F3">k</tspan>
165
+ </text>
166
+ </svg>
@@ -0,0 +1,98 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="-15 -25 45 45" width="500" height="500">
2
+ <defs>
3
+ <style>
4
+ .body-magic {
5
+ transform-origin: 7.5px 15px;
6
+ animation: float-body 3s infinite ease-in-out;
7
+ }
8
+ .arm-wand {
9
+ transform-origin: 14px 10px;
10
+ animation: wave-wand 3s infinite ease-in-out;
11
+ }
12
+ .arm-l-magic {
13
+ transform-origin: 1px 10px;
14
+ animation: wave-magic 3s infinite ease-in-out;
15
+ }
16
+ .eyes-magic {
17
+ animation: blink-magic 3s infinite;
18
+ }
19
+ .magic-star {
20
+ opacity: 0;
21
+ animation: sparkle-magic 2s infinite ease-out;
22
+ }
23
+ .s1 { animation-delay: 0s; fill: #FFD700; }
24
+ .s2 { animation-delay: 0.5s; fill: #40C4FF; }
25
+ .s3 { animation-delay: 1s; fill: #B388FF; }
26
+ .s4 { animation-delay: 1.5s; fill: #FF8A80; }
27
+
28
+ @keyframes float-body {
29
+ 0%, 100% { transform: translateY(0); }
30
+ 50% { transform: translateY(-2px); }
31
+ }
32
+ @keyframes wave-wand {
33
+ 0%, 100% { transform: rotate(-20deg); }
34
+ 50% { transform: rotate(-120deg); }
35
+ }
36
+ @keyframes wave-magic {
37
+ 0%, 100% { transform: rotate(20deg); }
38
+ 50% { transform: rotate(120deg); }
39
+ }
40
+ @keyframes blink-magic {
41
+ 0%, 40% { transform: scaleY(0.1); }
42
+ 45%, 95% { transform: scaleY(1); }
43
+ 100% { transform: scaleY(0.1); }
44
+ }
45
+ @keyframes sparkle-magic {
46
+ 0% { transform: translate(14px, 4px) scale(0) rotate(0deg); opacity: 0; }
47
+ 20% { opacity: 1; }
48
+ 100% { transform: translate(14px, -15px) scale(1.5) rotate(180deg); opacity: 0; }
49
+ }
50
+ </style>
51
+ <g id="star">
52
+ <polygon points="0,-2 0.5,-0.5 2,0 0.5,0.5 0,2 -0.5,0.5 -2,0 -0.5,-0.5"/>
53
+ </g>
54
+ </defs>
55
+
56
+ <rect id="ground-shadow" x="3" y="15" width="9" height="1" fill="#000000" opacity="0.4"/>
57
+
58
+ <!-- Magic Stars -->
59
+ <g>
60
+ <use href="#star" class="magic-star s1"/>
61
+ <use href="#star" class="magic-star s2" transform="translate(-10, 0)"/>
62
+ <use href="#star" class="magic-star s3" transform="translate(5, -5)"/>
63
+ <use href="#star" class="magic-star s4" transform="translate(-5, -10)"/>
64
+ </g>
65
+
66
+ <g class="body-magic">
67
+ <g id="legs" fill="#DE886D">
68
+ <rect x="3" y="13" width="1" height="2"/>
69
+ <rect x="5" y="13" width="1" height="2"/>
70
+ <rect x="9" y="13" width="1" height="2"/>
71
+ <rect x="11" y="13" width="1" height="2"/>
72
+ </g>
73
+
74
+ <g id="body-color-group" fill="#DE886D">
75
+ <rect x="2" y="6" width="11" height="7"/>
76
+ <g class="arm-l-magic"><rect x="0" y="9" width="2" height="2"/></g>
77
+ </g>
78
+
79
+ <g fill="#000000" class="eyes-magic" transform-origin="7.5px 9px">
80
+ <rect x="4" y="8" width="1" height="2"/>
81
+ <rect x="10" y="8" width="1" height="2"/>
82
+ </g>
83
+
84
+ <!-- Wizard Hat -->
85
+ <g transform="translate(7.5, 6)">
86
+ <polygon points="-4,0 4,0 0,-6" fill="#673AB7"/>
87
+ <rect x="-5" y="0" width="10" height="1" fill="#512DA8"/>
88
+ <polygon points="0,-3 0.5,-2.5 1.5,-2.5 0.75,-1.75 1,-0.5 0,-1.25 -1,-0.5 -0.75,-1.75 -1.5,-2.5 -0.5,-2.5" fill="#FFC107"/>
89
+ </g>
90
+
91
+ <!-- Wand arm (on top of hat and eyes) -->
92
+ <g class="arm-wand" fill="#DE886D">
93
+ <rect x="13" y="9" width="2" height="2"/>
94
+ <rect x="13.5" y="4" width="1" height="6" fill="#8D6E63"/>
95
+ <rect x="13.5" y="4" width="1" height="1" fill="#FFD700"/>
96
+ </g>
97
+ </g>
98
+ </svg>
Binary file
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ const electron = require('electron');
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ spawn(electron, [path.join(__dirname, '..')], { stdio: 'inherit' });
package/main.js ADDED
@@ -0,0 +1,86 @@
1
+ const { app, BrowserWindow, ipcMain, screen, Tray, Menu, nativeImage } = require('electron');
2
+ const path = require('path');
3
+
4
+ let win;
5
+ let tray;
6
+
7
+ app.commandLine.appendSwitch('disable-background-timer-throttling');
8
+
9
+ function createWindow() {
10
+ win = new BrowserWindow({
11
+ width: 128,
12
+ height: 128,
13
+ transparent: true,
14
+ frame: false,
15
+ alwaysOnTop: true,
16
+ skipTaskbar: true,
17
+ resizable: false,
18
+ hasShadow: false,
19
+ paintWhenInitiallyHidden: false,
20
+ webPreferences: {
21
+ preload: path.join(__dirname, 'preload.js'),
22
+ contextIsolation: true,
23
+ nodeIntegration: false,
24
+ backgroundThrottling: false,
25
+ },
26
+ });
27
+
28
+ win.loadFile(path.join(__dirname, 'renderer', 'index.html'));
29
+
30
+ // win.webContents.openDevTools(); // Debug için
31
+
32
+ win.on('closed', () => {
33
+ win = null;
34
+ });
35
+ }
36
+
37
+ function createTray() {
38
+ // Not: assets/tray-icon.png dosyası olmalı
39
+ const iconPath = path.join(__dirname, 'assets', 'tray-icon.ico');
40
+ const icon = nativeImage.createFromPath(iconPath);
41
+
42
+ tray = new Tray(icon);
43
+ const contextMenu = Menu.buildFromTemplate([
44
+ { label: 'Show', click: () => win.show() },
45
+ { label: 'Hide', click: () => win.hide() },
46
+ { type: 'separator' },
47
+ { label: 'Quit', click: () => app.quit() }
48
+ ]);
49
+
50
+ tray.setToolTip('Claude Pet');
51
+ tray.setContextMenu(contextMenu);
52
+ }
53
+
54
+ app.whenReady().then(() => {
55
+ createWindow();
56
+ createTray();
57
+
58
+ app.setLoginItemSettings({
59
+ openAtLogin: true,
60
+ name: 'ClaudePet'
61
+ });
62
+
63
+ app.on('activate', () => {
64
+ if (BrowserWindow.getAllWindows().length === 0) {
65
+ createWindow();
66
+ }
67
+ });
68
+ });
69
+
70
+ app.on('window-all-closed', () => {
71
+ if (process.platform !== 'darwin') {
72
+ app.quit();
73
+ }
74
+ });
75
+
76
+ // IPC: Renderer'dan pozisyon güncellemesi
77
+ ipcMain.on('move-window', (event, { x, y }) => {
78
+ if (win) {
79
+ win.setPosition(Math.round(x), Math.round(y));
80
+ }
81
+ });
82
+
83
+ // IPC: Ekran boyutunu gönder
84
+ ipcMain.handle('get-screen-size', () => {
85
+ return screen.getPrimaryDisplay().workAreaSize;
86
+ });
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "clawd-desktop",
3
+ "version": "1.0.0",
4
+ "description": "A pixel-art Claude mascot that lives on your desktop",
5
+ "main": "main.js",
6
+ "bin": {
7
+ "clawd-desktop": "./bin/claude-pet.js"
8
+ },
9
+ "files": [
10
+ "main.js",
11
+ "preload.js",
12
+ "renderer/",
13
+ "assets/",
14
+ "bin/"
15
+ ],
16
+ "scripts": {
17
+ "start": "electron .",
18
+ "build": "electron-builder",
19
+ "test": "echo \"No tests\" && exit 0"
20
+ },
21
+ "keywords": [
22
+ "claude",
23
+ "claude-code",
24
+ "desktop-pet",
25
+ "electron",
26
+ "pixel-art",
27
+ "mascot",
28
+ "windows"
29
+ ],
30
+ "author": "KebeliSamet0",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "electron": "^30.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "electron-builder": "^24.13.3"
37
+ }
38
+ }
package/preload.js ADDED
@@ -0,0 +1,6 @@
1
+ const { contextBridge, ipcRenderer } = require('electron');
2
+
3
+ contextBridge.exposeInMainWorld('electronAPI', {
4
+ moveWindow: (pos) => ipcRenderer.send('move-window', pos),
5
+ getScreenSize: () => ipcRenderer.invoke('get-screen-size')
6
+ });