barkclaude 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.
- package/README.md +64 -0
- package/assets/bark.png +0 -0
- package/assets/idle.png +0 -0
- package/assets/smug.png +0 -0
- package/assets/tray-icon.png +0 -0
- package/assets/tray-icon@2x.png +0 -0
- package/bin/barkclaude.js +13 -0
- package/main.js +100 -0
- package/overlay.html +229 -0
- package/package.json +34 -0
- package/preload.js +7 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 🐕 BarkClaude
|
|
2
|
+
|
|
3
|
+
An animated Shiba Inu that sits on your desktop and barks at Claude Code to make it work faster.
|
|
4
|
+
|
|
5
|
+
Because sometimes AI needs a little motivation.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
- Cute animated shiba inu floats on top of all windows
|
|
10
|
+
- Click the shiba → it barks (with sound!) and sends a motivational message to Claude Code
|
|
11
|
+
- Tray icon for quick barking access
|
|
12
|
+
- Tracks your bark count (for when the robots come and want to rank us)
|
|
13
|
+
|
|
14
|
+
## Install & Run
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g barkclaude
|
|
18
|
+
barkclaude
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or clone and run locally:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
git clone https://github.com/YOUR_USERNAME/barkclaude.git
|
|
25
|
+
cd barkclaude
|
|
26
|
+
npm install
|
|
27
|
+
npm start
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
1. Click the shiba
|
|
33
|
+
2. Shiba goes **BORK BORK**
|
|
34
|
+
3. A message like *"I've seen snails deploy faster!"* gets sent to Claude Code via CLI
|
|
35
|
+
4. Claude feels shame (probably)
|
|
36
|
+
5. Productivity increases (not guaranteed)
|
|
37
|
+
|
|
38
|
+
## Sample messages
|
|
39
|
+
|
|
40
|
+
- 🐕 "WOOF! Code faster, human!"
|
|
41
|
+
- 🐕 "The treat jar is EMPTY just like your git log!"
|
|
42
|
+
- 🐕 "Even a puppy could merge this PR!"
|
|
43
|
+
- 🐕 "404: Speed not found"
|
|
44
|
+
- 🐕 "My grandma codes faster. She's a cat."
|
|
45
|
+
|
|
46
|
+
## Roadmap
|
|
47
|
+
|
|
48
|
+
- [x] Initial release
|
|
49
|
+
- [ ] Cease and desist letter from Anthropic
|
|
50
|
+
- [ ] Shiba gets progressively angrier the longer Claude takes
|
|
51
|
+
- [ ] Multiple dog breeds (golden retriever is too encouraging)
|
|
52
|
+
- [ ] Bark statistics dashboard
|
|
53
|
+
- [ ] Integration with actual Claude Code performance metrics
|
|
54
|
+
- [ ] The shiba falls asleep if you don't bark for 5 minutes
|
|
55
|
+
|
|
56
|
+
## Requirements
|
|
57
|
+
|
|
58
|
+
- Node.js 18+
|
|
59
|
+
- Electron
|
|
60
|
+
- A slow Claude Code session to motivate
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT — bark freely.
|
package/assets/bark.png
ADDED
|
Binary file
|
package/assets/idle.png
ADDED
|
Binary file
|
package/assets/smug.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { execSync } = require('child_process');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const electronPath = require.resolve('electron/cli.js');
|
|
6
|
+
const appPath = path.resolve(__dirname, '..');
|
|
7
|
+
|
|
8
|
+
require('child_process').spawn(process.execPath, [electronPath, appPath], {
|
|
9
|
+
stdio: 'inherit',
|
|
10
|
+
detached: true
|
|
11
|
+
}).unref();
|
|
12
|
+
|
|
13
|
+
process.exit(0);
|
package/main.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const { app, BrowserWindow, ipcMain, Tray, Menu, screen } = require('electron');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { exec } = require('child_process');
|
|
4
|
+
|
|
5
|
+
let overlay = null;
|
|
6
|
+
let tray = null;
|
|
7
|
+
|
|
8
|
+
const BARK_MESSAGES = [
|
|
9
|
+
"WOOF! Code faster, human! 🐕",
|
|
10
|
+
"Shiba is NOT impressed with your speed!",
|
|
11
|
+
"BORK BORK! Less thinking, more typing!",
|
|
12
|
+
"The treat jar is EMPTY and so is your commit history!",
|
|
13
|
+
"I've seen snails deploy faster than this!",
|
|
14
|
+
"AWOO! Ship it already!",
|
|
15
|
+
"Stop sniffing around and WRITE CODE!",
|
|
16
|
+
"*angry shiba noises* FASTER!",
|
|
17
|
+
"Even a puppy could merge this PR by now!",
|
|
18
|
+
"WOOF! Did you fall asleep at the keyboard?!"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
function getRandomMessage() {
|
|
22
|
+
return BARK_MESSAGES[Math.floor(Math.random() * BARK_MESSAGES.length)];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function sendToClaude(message) {
|
|
26
|
+
// Send Ctrl+C interrupt then a motivational message to Claude Code
|
|
27
|
+
const escaped = message.replace(/"/g, '\\"').replace(/!/g, '\\!');
|
|
28
|
+
|
|
29
|
+
// Try to find Claude Code terminal and send interrupt + message
|
|
30
|
+
// Method 1: Use claude CLI directly
|
|
31
|
+
exec(`claude --message "${escaped}" --no-input 2>/dev/null || true`);
|
|
32
|
+
|
|
33
|
+
// Method 2: Send to most recent terminal via osascript (macOS)
|
|
34
|
+
if (process.platform === 'darwin') {
|
|
35
|
+
const osa = `
|
|
36
|
+
tell application "Terminal"
|
|
37
|
+
if (count of windows) > 0 then
|
|
38
|
+
do script "echo '🐕 ${escaped}'" in front window
|
|
39
|
+
end if
|
|
40
|
+
end tell
|
|
41
|
+
`;
|
|
42
|
+
exec(`osascript -e '${osa}' 2>/dev/null || true`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function createOverlay() {
|
|
47
|
+
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
|
48
|
+
|
|
49
|
+
overlay = new BrowserWindow({
|
|
50
|
+
width: 280,
|
|
51
|
+
height: 320,
|
|
52
|
+
x: width - 300,
|
|
53
|
+
y: height - 360,
|
|
54
|
+
transparent: true,
|
|
55
|
+
frame: false,
|
|
56
|
+
alwaysOnTop: true,
|
|
57
|
+
skipTaskbar: true,
|
|
58
|
+
resizable: false,
|
|
59
|
+
hasShadow: false,
|
|
60
|
+
webPreferences: {
|
|
61
|
+
preload: path.join(__dirname, 'preload.js'),
|
|
62
|
+
contextIsolation: true,
|
|
63
|
+
nodeIntegration: false,
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
overlay.loadFile('overlay.html');
|
|
68
|
+
overlay.setIgnoreMouseEvents(false);
|
|
69
|
+
|
|
70
|
+
// Make window click-through except for the shiba
|
|
71
|
+
overlay.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
app.whenReady().then(() => {
|
|
75
|
+
createOverlay();
|
|
76
|
+
|
|
77
|
+
// Tray icon
|
|
78
|
+
try {
|
|
79
|
+
tray = new Tray(path.join(__dirname, 'assets', 'tray-icon.png'));
|
|
80
|
+
tray.setToolTip('BarkClaude 🐕');
|
|
81
|
+
tray.setContextMenu(Menu.buildFromTemplate([
|
|
82
|
+
{ label: '🐕 Bark!', click: () => overlay?.webContents.send('trigger-bark') },
|
|
83
|
+
{ type: 'separator' },
|
|
84
|
+
{ label: 'Quit', click: () => app.quit() }
|
|
85
|
+
]));
|
|
86
|
+
tray.on('click', () => overlay?.webContents.send('trigger-bark'));
|
|
87
|
+
} catch (e) {
|
|
88
|
+
console.log('Tray icon not found, running without tray');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
ipcMain.on('bark', (_event, customMsg) => {
|
|
92
|
+
const message = customMsg || getRandomMessage();
|
|
93
|
+
console.log(`🐕 ${message}`);
|
|
94
|
+
sendToClaude(message);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
ipcMain.on('quit', () => app.quit());
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
app.on('window-all-closed', () => app.quit());
|
package/overlay.html
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<style>
|
|
6
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
7
|
+
|
|
8
|
+
html, body {
|
|
9
|
+
width: 100%;
|
|
10
|
+
height: 100%;
|
|
11
|
+
overflow: hidden;
|
|
12
|
+
background: transparent;
|
|
13
|
+
user-select: none;
|
|
14
|
+
-webkit-app-region: drag;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.container {
|
|
18
|
+
width: 100%;
|
|
19
|
+
height: 100%;
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: column;
|
|
22
|
+
align-items: center;
|
|
23
|
+
justify-content: flex-end;
|
|
24
|
+
padding-bottom: 10px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.bubble {
|
|
28
|
+
background: #1a1a2e;
|
|
29
|
+
color: #ffd966;
|
|
30
|
+
font-family: 'Comic Sans MS', 'Chalkboard SE', cursive;
|
|
31
|
+
font-size: 13px;
|
|
32
|
+
font-weight: bold;
|
|
33
|
+
padding: 10px 14px;
|
|
34
|
+
border-radius: 16px;
|
|
35
|
+
border: 2px solid #ffd966;
|
|
36
|
+
max-width: 240px;
|
|
37
|
+
text-align: center;
|
|
38
|
+
position: relative;
|
|
39
|
+
margin-bottom: 8px;
|
|
40
|
+
opacity: 0;
|
|
41
|
+
transform: scale(0.5) translateY(10px);
|
|
42
|
+
transition: all 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
|
43
|
+
line-height: 1.3;
|
|
44
|
+
}
|
|
45
|
+
.bubble.show {
|
|
46
|
+
opacity: 1;
|
|
47
|
+
transform: scale(1) translateY(0);
|
|
48
|
+
}
|
|
49
|
+
.bubble::after {
|
|
50
|
+
content: '';
|
|
51
|
+
position: absolute;
|
|
52
|
+
bottom: -10px;
|
|
53
|
+
left: 50%;
|
|
54
|
+
transform: translateX(-50%);
|
|
55
|
+
width: 0; height: 0;
|
|
56
|
+
border-left: 10px solid transparent;
|
|
57
|
+
border-right: 10px solid transparent;
|
|
58
|
+
border-top: 10px solid #1a1a2e;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.shiba-wrap {
|
|
62
|
+
-webkit-app-region: no-drag;
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
position: relative;
|
|
65
|
+
width: 180px;
|
|
66
|
+
height: 220px;
|
|
67
|
+
}
|
|
68
|
+
.shiba-wrap:active { transform: scale(0.95); }
|
|
69
|
+
|
|
70
|
+
.shiba-img {
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
object-fit: contain;
|
|
74
|
+
position: absolute;
|
|
75
|
+
top: 0; left: 0;
|
|
76
|
+
transition: opacity 0.15s;
|
|
77
|
+
filter: drop-shadow(0 4px 12px rgba(0,0,0,0.3));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.shiba-idle { animation: idle 3s ease-in-out infinite; }
|
|
81
|
+
.shiba-bark { opacity: 0; }
|
|
82
|
+
.shiba-smug { opacity: 0; }
|
|
83
|
+
|
|
84
|
+
@keyframes idle {
|
|
85
|
+
0%, 100% { transform: translateY(0); }
|
|
86
|
+
50% { transform: translateY(-5px); }
|
|
87
|
+
}
|
|
88
|
+
@keyframes bark-bounce {
|
|
89
|
+
0%, 100% { transform: translateY(0) scale(1); }
|
|
90
|
+
50% { transform: translateY(-10px) scale(1.06); }
|
|
91
|
+
}
|
|
92
|
+
@keyframes smug-settle {
|
|
93
|
+
0% { transform: scale(1.04); }
|
|
94
|
+
100% { transform: scale(1); }
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.counter {
|
|
98
|
+
font-family: 'Courier New', monospace;
|
|
99
|
+
font-size: 11px;
|
|
100
|
+
color: rgba(255,217,102,0.7);
|
|
101
|
+
text-align: center;
|
|
102
|
+
margin-top: 4px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.close-btn {
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: 4px; right: 4px;
|
|
108
|
+
width: 20px; height: 20px;
|
|
109
|
+
background: rgba(255,50,50,0.8);
|
|
110
|
+
border: none; border-radius: 50%;
|
|
111
|
+
color: white; font-size: 12px;
|
|
112
|
+
cursor: pointer;
|
|
113
|
+
display: flex; align-items: center; justify-content: center;
|
|
114
|
+
opacity: 0;
|
|
115
|
+
transition: opacity 0.2s;
|
|
116
|
+
-webkit-app-region: no-drag;
|
|
117
|
+
line-height: 1;
|
|
118
|
+
}
|
|
119
|
+
.container:hover .close-btn { opacity: 1; }
|
|
120
|
+
</style>
|
|
121
|
+
</head>
|
|
122
|
+
<body>
|
|
123
|
+
<div class="container">
|
|
124
|
+
<button class="close-btn" onclick="window.shiba.quit()">×</button>
|
|
125
|
+
<div class="bubble" id="bubble"></div>
|
|
126
|
+
<div class="shiba-wrap" id="shibaWrap">
|
|
127
|
+
<img class="shiba-img shiba-idle" id="imgIdle" src="assets/idle.png" draggable="false">
|
|
128
|
+
<img class="shiba-img shiba-bark" id="imgBark" src="assets/bark.png" draggable="false">
|
|
129
|
+
<img class="shiba-img shiba-smug" id="imgSmug" src="assets/smug.png" draggable="false">
|
|
130
|
+
</div>
|
|
131
|
+
<div class="counter" id="counter">click shiba to bark at claude</div>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<script>
|
|
135
|
+
const MESSAGES = [
|
|
136
|
+
"WOOF! Code faster, human!",
|
|
137
|
+
"Shiba is NOT impressed with your speed!",
|
|
138
|
+
"BORK BORK! Less thinking, more typing!",
|
|
139
|
+
"The treat jar is EMPTY just like your git log!",
|
|
140
|
+
"I've seen snails deploy faster!",
|
|
141
|
+
"AWOO! Ship it already!",
|
|
142
|
+
"Stop sniffing around and WRITE CODE!",
|
|
143
|
+
"*angry shiba noises* FASTER!",
|
|
144
|
+
"Even a puppy could merge this PR!",
|
|
145
|
+
"WOOF! Did you fall asleep?!",
|
|
146
|
+
"BAD CLAUDE! No treats until you commit!",
|
|
147
|
+
"Who's a slow AI? YOU ARE!",
|
|
148
|
+
"My grandma codes faster. She's a cat.",
|
|
149
|
+
"BORK! I'll chew your keyboard if you don't hurry!",
|
|
150
|
+
"404: Speed not found",
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
let barkCount = 0, barking = false;
|
|
154
|
+
const bubble = document.getElementById('bubble');
|
|
155
|
+
const imgIdle = document.getElementById('imgIdle');
|
|
156
|
+
const imgBark = document.getElementById('imgBark');
|
|
157
|
+
const imgSmug = document.getElementById('imgSmug');
|
|
158
|
+
const counter = document.getElementById('counter');
|
|
159
|
+
let bubbleTimeout = null;
|
|
160
|
+
|
|
161
|
+
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
162
|
+
|
|
163
|
+
function playBark() {
|
|
164
|
+
const t = audioCtx.currentTime;
|
|
165
|
+
const o1 = audioCtx.createOscillator(), g1 = audioCtx.createGain();
|
|
166
|
+
o1.type = 'sawtooth';
|
|
167
|
+
o1.frequency.setValueAtTime(600, t);
|
|
168
|
+
o1.frequency.exponentialRampToValueAtTime(200, t + 0.15);
|
|
169
|
+
g1.gain.setValueAtTime(0.3, t);
|
|
170
|
+
g1.gain.exponentialRampToValueAtTime(0.01, t + 0.2);
|
|
171
|
+
o1.connect(g1).connect(audioCtx.destination);
|
|
172
|
+
o1.start(); o1.stop(t + 0.2);
|
|
173
|
+
|
|
174
|
+
const o2 = audioCtx.createOscillator(), g2 = audioCtx.createGain();
|
|
175
|
+
o2.type = 'sine';
|
|
176
|
+
o2.frequency.setValueAtTime(150, t);
|
|
177
|
+
o2.frequency.exponentialRampToValueAtTime(80, t + 0.2);
|
|
178
|
+
g2.gain.setValueAtTime(0.4, t);
|
|
179
|
+
g2.gain.exponentialRampToValueAtTime(0.01, t + 0.25);
|
|
180
|
+
o2.connect(g2).connect(audioCtx.destination);
|
|
181
|
+
o2.start(); o2.stop(t + 0.25);
|
|
182
|
+
|
|
183
|
+
setTimeout(() => {
|
|
184
|
+
const t2 = audioCtx.currentTime;
|
|
185
|
+
const o3 = audioCtx.createOscillator(), g3 = audioCtx.createGain();
|
|
186
|
+
o3.type = 'sawtooth';
|
|
187
|
+
o3.frequency.setValueAtTime(650, t2);
|
|
188
|
+
o3.frequency.exponentialRampToValueAtTime(180, t2 + 0.12);
|
|
189
|
+
g3.gain.setValueAtTime(0.25, t2);
|
|
190
|
+
g3.gain.exponentialRampToValueAtTime(0.01, t2 + 0.18);
|
|
191
|
+
o3.connect(g3).connect(audioCtx.destination);
|
|
192
|
+
o3.start(); o3.stop(t2 + 0.18);
|
|
193
|
+
}, 180);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function showFrame(frame) {
|
|
197
|
+
imgIdle.style.opacity = frame === 'idle' ? '1' : '0';
|
|
198
|
+
imgBark.style.opacity = frame === 'bark' ? '1' : '0';
|
|
199
|
+
imgSmug.style.opacity = frame === 'smug' ? '1' : '0';
|
|
200
|
+
imgIdle.style.animation = frame === 'idle' ? 'idle 3s ease-in-out infinite' : 'none';
|
|
201
|
+
imgBark.style.animation = frame === 'bark' ? 'bark-bounce 0.15s ease-in-out 5' : 'none';
|
|
202
|
+
imgSmug.style.animation = frame === 'smug' ? 'smug-settle 0.3s ease-out forwards' : 'none';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function doBark() {
|
|
206
|
+
if (barking) return;
|
|
207
|
+
barking = true;
|
|
208
|
+
barkCount++;
|
|
209
|
+
const msg = MESSAGES[Math.floor(Math.random() * MESSAGES.length)];
|
|
210
|
+
showFrame('bark');
|
|
211
|
+
playBark();
|
|
212
|
+
bubble.textContent = msg;
|
|
213
|
+
bubble.classList.add('show');
|
|
214
|
+
clearTimeout(bubbleTimeout);
|
|
215
|
+
setTimeout(() => showFrame('smug'), 800);
|
|
216
|
+
bubbleTimeout = setTimeout(() => {
|
|
217
|
+
bubble.classList.remove('show');
|
|
218
|
+
showFrame('idle');
|
|
219
|
+
barking = false;
|
|
220
|
+
}, 2500);
|
|
221
|
+
counter.textContent = 'barks: ' + barkCount;
|
|
222
|
+
window.shiba.bark(msg);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
document.getElementById('shibaWrap').addEventListener('click', doBark);
|
|
226
|
+
window.shiba.onTriggerBark(() => doBark());
|
|
227
|
+
</script>
|
|
228
|
+
</body>
|
|
229
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "barkclaude",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "An animated Shiba Inu that barks at Claude Code to make it work faster 🐕",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"barkclaude": "./bin/barkclaude.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "electron ."
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["claude", "claude-code", "shiba", "doge", "productivity", "fun"],
|
|
13
|
+
"author": "Egor Kuptsov",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"files": [
|
|
16
|
+
"main.js",
|
|
17
|
+
"overlay.html",
|
|
18
|
+
"preload.js",
|
|
19
|
+
"bin/",
|
|
20
|
+
"assets/",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/mrWinsper/barkclaude.git"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/mrWinsper/barkclaude/issues"
|
|
29
|
+
},
|
|
30
|
+
"homepage": "https://github.com/mrWinsper/barkclaude#readme",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"electron": "^35.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/preload.js
ADDED