@pulso/companion 0.1.1 → 0.1.3
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/dist/index.js +54 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -113,7 +113,44 @@ async function handleCommand(command, params) {
|
|
|
113
113
|
const query = params.query;
|
|
114
114
|
if (!query) return { success: false, error: "Missing search query" };
|
|
115
115
|
await runShell(`open "spotify:search:${encodeURIComponent(query)}"`);
|
|
116
|
-
|
|
116
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
117
|
+
await runAppleScript(`
|
|
118
|
+
tell application "Spotify" to activate
|
|
119
|
+
delay 0.5
|
|
120
|
+
tell application "System Events"
|
|
121
|
+
tell process "Spotify"
|
|
122
|
+
key code 36
|
|
123
|
+
end tell
|
|
124
|
+
end tell
|
|
125
|
+
`);
|
|
126
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
127
|
+
try {
|
|
128
|
+
const track = await runAppleScript('tell application "Spotify" to name of current track');
|
|
129
|
+
const artist = await runAppleScript('tell application "Spotify" to artist of current track');
|
|
130
|
+
return { success: true, data: { searched: query, nowPlaying: `${track} - ${artist}` } };
|
|
131
|
+
} catch {
|
|
132
|
+
return { success: true, data: { searched: query, note: "Search opened and play triggered" } };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
case "volume": {
|
|
136
|
+
const level = params.level;
|
|
137
|
+
if (level === void 0 || level < 0 || level > 100) return { success: false, error: "Volume must be 0-100" };
|
|
138
|
+
await runAppleScript(`tell application "Spotify" to set sound volume to ${level}`);
|
|
139
|
+
return { success: true, data: { volume: level } };
|
|
140
|
+
}
|
|
141
|
+
case "shuffle": {
|
|
142
|
+
const enabled = params.enabled;
|
|
143
|
+
await runAppleScript(`tell application "Spotify" to set shuffling to ${enabled ? "true" : "false"}`);
|
|
144
|
+
return { success: true, data: { shuffling: enabled } };
|
|
145
|
+
}
|
|
146
|
+
case "repeat": {
|
|
147
|
+
const mode = params.mode;
|
|
148
|
+
if (!mode) return { success: false, error: "Missing mode (off, context, track)" };
|
|
149
|
+
const repeatMap = { off: "off", context: "context", track: "track" };
|
|
150
|
+
const val = repeatMap[mode];
|
|
151
|
+
if (!val) return { success: false, error: "Mode must be: off, context, or track" };
|
|
152
|
+
await runAppleScript(`tell application "Spotify" to set repeating to ${val !== "off"}`);
|
|
153
|
+
return { success: true, data: { repeating: mode } };
|
|
117
154
|
}
|
|
118
155
|
default:
|
|
119
156
|
return { success: false, error: `Unknown Spotify action: ${action}` };
|
|
@@ -177,6 +214,8 @@ async function handleCommand(command, params) {
|
|
|
177
214
|
}
|
|
178
215
|
var ws = null;
|
|
179
216
|
var reconnectTimer = null;
|
|
217
|
+
var heartbeatTimer = null;
|
|
218
|
+
var HEARTBEAT_INTERVAL = 3e4;
|
|
180
219
|
function connect() {
|
|
181
220
|
console.log("\u{1F50C} Connecting to Pulso...");
|
|
182
221
|
console.log(` ${WS_URL.replace(/token=.*/, "token=***")}`);
|
|
@@ -199,6 +238,12 @@ function connect() {
|
|
|
199
238
|
console.log(` Access: ${ACCESS_LEVEL === "full" ? "\u{1F513} Full (unrestricted)" : "\u{1F512} Sandboxed (safe dirs only)"}`);
|
|
200
239
|
console.log(" Waiting for commands from Pulso agent...");
|
|
201
240
|
ws.send(JSON.stringify({ type: "extension_ready" }));
|
|
241
|
+
if (heartbeatTimer) clearInterval(heartbeatTimer);
|
|
242
|
+
heartbeatTimer = setInterval(() => {
|
|
243
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
244
|
+
ws.send(JSON.stringify({ type: "ping" }));
|
|
245
|
+
}
|
|
246
|
+
}, HEARTBEAT_INTERVAL);
|
|
202
247
|
});
|
|
203
248
|
ws.on("message", async (raw) => {
|
|
204
249
|
try {
|
|
@@ -207,6 +252,9 @@ function connect() {
|
|
|
207
252
|
console.log(` \u2713 Server: ${msg.message}`);
|
|
208
253
|
return;
|
|
209
254
|
}
|
|
255
|
+
if (msg.type === "pong") {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
210
258
|
if (msg.id && msg.command) {
|
|
211
259
|
console.log(`
|
|
212
260
|
\u26A1 Command: ${msg.command}`, msg.params ? JSON.stringify(msg.params).slice(0, 200) : "");
|
|
@@ -223,6 +271,10 @@ function connect() {
|
|
|
223
271
|
ws.on("close", (code, reason) => {
|
|
224
272
|
console.log(`
|
|
225
273
|
\u{1F50C} Disconnected (${code}: ${reason.toString() || "unknown"})`);
|
|
274
|
+
if (heartbeatTimer) {
|
|
275
|
+
clearInterval(heartbeatTimer);
|
|
276
|
+
heartbeatTimer = null;
|
|
277
|
+
}
|
|
226
278
|
scheduleReconnect();
|
|
227
279
|
});
|
|
228
280
|
ws.on("error", (err) => {
|
|
@@ -239,7 +291,7 @@ function scheduleReconnect() {
|
|
|
239
291
|
}
|
|
240
292
|
console.log("");
|
|
241
293
|
console.log(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
|
|
242
|
-
console.log(" \u2551 \u{1FAC0} Pulso Mac Companion v0.1.
|
|
294
|
+
console.log(" \u2551 \u{1FAC0} Pulso Mac Companion v0.1.3 \u2551");
|
|
243
295
|
console.log(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
|
|
244
296
|
console.log("");
|
|
245
297
|
connect();
|