@walldock/agent 0.1.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.
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerStartup = registerStartup;
37
+ exports.unregisterStartup = unregisterStartup;
38
+ exports.startupDescription = startupDescription;
39
+ exports.getGlobalBin = getGlobalBin;
40
+ const fs = __importStar(require("node:fs/promises"));
41
+ const path = __importStar(require("node:path"));
42
+ const os = __importStar(require("node:os"));
43
+ const node_child_process_1 = require("node:child_process");
44
+ const node_util_1 = require("node:util");
45
+ const exec = (0, node_util_1.promisify)(node_child_process_1.execFile);
46
+ // ─── Global bin resolution ────────────────────────────────────────────────────
47
+ async function resolveGlobalBin() {
48
+ let prefix;
49
+ try {
50
+ const { stdout } = await exec('npm', ['prefix', '-g']);
51
+ prefix = stdout.trim();
52
+ }
53
+ catch {
54
+ throw new Error('Could not determine npm global prefix.\n' +
55
+ 'Make sure npm is installed and run: npm install -g @walldock/agent');
56
+ }
57
+ const binName = process.platform === 'win32' ? 'walldock-agent.cmd' : 'walldock-agent';
58
+ const binPath = process.platform === 'win32'
59
+ ? path.join(prefix, binName)
60
+ : path.join(prefix, 'bin', binName);
61
+ try {
62
+ await fs.access(binPath);
63
+ }
64
+ catch {
65
+ throw new Error(`walldock-agent is not globally installed at ${binPath}.\n` +
66
+ 'Run: npm install -g @walldock/agent');
67
+ }
68
+ return binPath;
69
+ }
70
+ // ─── macOS ───────────────────────────────────────────────────────────────────
71
+ const LAUNCH_AGENTS_DIR = path.join(os.homedir(), 'Library', 'LaunchAgents');
72
+ const PLIST_PATH = path.join(LAUNCH_AGENTS_DIR, 'com.walldock.agent.plist');
73
+ const PLIST_LABEL = 'com.walldock.agent';
74
+ function plistContent(binPath) {
75
+ return `<?xml version="1.0" encoding="UTF-8"?>
76
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
77
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
78
+ <plist version="1.0">
79
+ <dict>
80
+ <key>Label</key>
81
+ <string>${PLIST_LABEL}</string>
82
+ <key>ProgramArguments</key>
83
+ <array>
84
+ <string>${binPath}</string>
85
+ <string>--daemon</string>
86
+ </array>
87
+ <key>RunAtLoad</key>
88
+ <true/>
89
+ <key>KeepAlive</key>
90
+ <false/>
91
+ <key>StandardOutPath</key>
92
+ <string>${path.join(os.homedir(), 'Library', 'Logs', 'walldock-agent.log')}</string>
93
+ <key>StandardErrorPath</key>
94
+ <string>${path.join(os.homedir(), 'Library', 'Logs', 'walldock-agent.log')}</string>
95
+ </dict>
96
+ </plist>
97
+ `;
98
+ }
99
+ async function registerMacOS() {
100
+ const binPath = await resolveGlobalBin();
101
+ await fs.mkdir(LAUNCH_AGENTS_DIR, { recursive: true });
102
+ await fs.writeFile(PLIST_PATH, plistContent(binPath), 'utf8');
103
+ await exec('launchctl', ['load', '-w', PLIST_PATH]).catch(() => undefined);
104
+ }
105
+ async function unregisterMacOS() {
106
+ await exec('launchctl', ['unload', PLIST_PATH]).catch(() => undefined);
107
+ await fs.unlink(PLIST_PATH).catch(() => undefined);
108
+ }
109
+ // ─── Windows ─────────────────────────────────────────────────────────────────
110
+ const REG_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run';
111
+ const REG_VALUE = 'WalldockAgent';
112
+ async function registerWindows() {
113
+ const binPath = await resolveGlobalBin();
114
+ const cmd = `"${binPath}" --daemon`;
115
+ await exec('reg', ['add', REG_KEY, '/v', REG_VALUE, '/t', 'REG_SZ', '/d', cmd, '/f']);
116
+ }
117
+ async function unregisterWindows() {
118
+ await exec('reg', ['delete', REG_KEY, '/v', REG_VALUE, '/f']).catch(() => undefined);
119
+ }
120
+ // ─── Linux ───────────────────────────────────────────────────────────────────
121
+ const SYSTEMD_USER_DIR = path.join(os.homedir(), '.config', 'systemd', 'user');
122
+ const SERVICE_PATH = path.join(SYSTEMD_USER_DIR, 'walldock-agent.service');
123
+ const AUTOSTART_DIR = path.join(os.homedir(), '.config', 'autostart');
124
+ const DESKTOP_PATH = path.join(AUTOSTART_DIR, 'walldock-agent.desktop');
125
+ function serviceContent(binPath) {
126
+ return `[Unit]
127
+ Description=Walldock Agent
128
+ After=network-online.target
129
+ Wants=network-online.target
130
+
131
+ [Service]
132
+ ExecStart=${binPath} --daemon
133
+ Restart=on-failure
134
+ RestartSec=10s
135
+
136
+ [Install]
137
+ WantedBy=default.target
138
+ `;
139
+ }
140
+ function desktopContent(binPath) {
141
+ return `[Desktop Entry]
142
+ Type=Application
143
+ Name=Walldock Agent
144
+ Exec=${binPath} --daemon
145
+ Hidden=false
146
+ NoDisplay=false
147
+ X-GNOME-Autostart-enabled=true
148
+ `;
149
+ }
150
+ async function systemdAvailable() {
151
+ try {
152
+ await exec('systemctl', ['--user', 'status'], { timeout: 3000 });
153
+ return true;
154
+ }
155
+ catch (e) {
156
+ // exit code 3 means "running but no units loaded" — systemd is present
157
+ return e.code === 3;
158
+ }
159
+ }
160
+ async function registerLinux() {
161
+ const binPath = await resolveGlobalBin();
162
+ if (await systemdAvailable()) {
163
+ await fs.mkdir(SYSTEMD_USER_DIR, { recursive: true });
164
+ await fs.writeFile(SERVICE_PATH, serviceContent(binPath), 'utf8');
165
+ await exec('systemctl', ['--user', 'daemon-reload']).catch(() => undefined);
166
+ await exec('systemctl', ['--user', 'enable', '--now', 'walldock-agent.service']).catch(() => undefined);
167
+ return;
168
+ }
169
+ // Fallback: XDG autostart .desktop file
170
+ await fs.mkdir(AUTOSTART_DIR, { recursive: true });
171
+ await fs.writeFile(DESKTOP_PATH, desktopContent(binPath), 'utf8');
172
+ }
173
+ async function unregisterLinux() {
174
+ await exec('systemctl', ['--user', 'disable', '--now', 'walldock-agent.service']).catch(() => undefined);
175
+ await fs.unlink(SERVICE_PATH).catch(() => undefined);
176
+ await fs.unlink(DESKTOP_PATH).catch(() => undefined);
177
+ }
178
+ // ─── Public API ──────────────────────────────────────────────────────────────
179
+ async function registerStartup() {
180
+ if (process.platform === 'darwin')
181
+ return registerMacOS();
182
+ if (process.platform === 'win32')
183
+ return registerWindows();
184
+ return registerLinux();
185
+ }
186
+ async function unregisterStartup() {
187
+ if (process.platform === 'darwin')
188
+ return unregisterMacOS();
189
+ if (process.platform === 'win32')
190
+ return unregisterWindows();
191
+ return unregisterLinux();
192
+ }
193
+ function startupDescription() {
194
+ if (process.platform === 'darwin')
195
+ return `LaunchAgent at ${PLIST_PATH}`;
196
+ if (process.platform === 'win32')
197
+ return `Registry: ${REG_KEY}\\${REG_VALUE}`;
198
+ return `systemd user service (or ${DESKTOP_PATH})`;
199
+ }
200
+ /** Returns the resolved global bin path, or null if not globally installed. */
201
+ async function getGlobalBin() {
202
+ try {
203
+ return await resolveGlobalBin();
204
+ }
205
+ catch {
206
+ return null;
207
+ }
208
+ }
package/dist/sync.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { AgentApi } from './api';
2
+ export interface SyncContext {
3
+ token: string;
4
+ deviceId: string;
5
+ }
6
+ export type ConnectionStatus = 'idle' | 'online' | 'error';
7
+ export interface SyncCallbacks {
8
+ onTick(status: ConnectionStatus, lastSyncAt?: string): void;
9
+ onLog(msg: string): void;
10
+ }
11
+ export declare class SyncService {
12
+ private readonly api;
13
+ private readonly callbacks;
14
+ private context;
15
+ private timer;
16
+ private sse;
17
+ private tickInFlight;
18
+ private lastScreensFingerprint;
19
+ /** Per-process cache: stableId → wallpaperId we successfully applied */
20
+ private readonly applied;
21
+ constructor(api: AgentApi, callbacks: SyncCallbacks);
22
+ start(context: SyncContext): void;
23
+ stop(): void;
24
+ syncNow(): Promise<void>;
25
+ private scheduleNext;
26
+ private runTick;
27
+ private doTick;
28
+ private handlePush;
29
+ private reportScreensIfChanged;
30
+ private fetchCommands;
31
+ private reconcile;
32
+ }
package/dist/sync.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SyncService = void 0;
4
+ const index_1 = require("./screens/index");
5
+ const index_2 = require("./wallpaper/index");
6
+ const cache_1 = require("./cache");
7
+ const sse_1 = require("./sse");
8
+ const POLL_INTERVAL_MS = 15_000;
9
+ class SyncService {
10
+ api;
11
+ callbacks;
12
+ context = null;
13
+ timer = null;
14
+ sse = null;
15
+ tickInFlight = null;
16
+ lastScreensFingerprint = null;
17
+ /** Per-process cache: stableId → wallpaperId we successfully applied */
18
+ applied = new Map();
19
+ constructor(api, callbacks) {
20
+ this.api = api;
21
+ this.callbacks = callbacks;
22
+ }
23
+ start(context) {
24
+ this.stop();
25
+ this.context = context;
26
+ this.lastScreensFingerprint = null;
27
+ this.applied.clear();
28
+ const sseUrl = `${this.api.endpoint.replace('/api/graphql', '')}/api/agent/events?token=${encodeURIComponent(context.token)}`;
29
+ this.sse = (0, sse_1.connectSse)(sseUrl, (type) => {
30
+ if (type === 'assignment-changed') {
31
+ void this.handlePush();
32
+ }
33
+ }, () => this.callbacks.onLog('SSE connected'));
34
+ void this.runTick().finally(() => this.scheduleNext());
35
+ }
36
+ stop() {
37
+ if (this.timer) {
38
+ clearTimeout(this.timer);
39
+ this.timer = null;
40
+ }
41
+ this.sse?.stop();
42
+ this.sse = null;
43
+ this.context = null;
44
+ }
45
+ async syncNow() {
46
+ if (this.context)
47
+ await this.runTick();
48
+ }
49
+ scheduleNext() {
50
+ if (!this.context)
51
+ return;
52
+ this.timer = setTimeout(() => {
53
+ this.timer = null;
54
+ void this.runTick().finally(() => this.scheduleNext());
55
+ }, POLL_INTERVAL_MS);
56
+ }
57
+ runTick() {
58
+ if (this.tickInFlight)
59
+ return this.tickInFlight;
60
+ const ctx = this.context;
61
+ if (!ctx)
62
+ return Promise.resolve();
63
+ return (this.tickInFlight = this.doTick(ctx));
64
+ }
65
+ async doTick(ctx) {
66
+ try {
67
+ await this.reportScreensIfChanged(ctx);
68
+ await this.fetchCommands(ctx);
69
+ await this.reconcile(ctx);
70
+ }
71
+ finally {
72
+ this.tickInFlight = null;
73
+ }
74
+ }
75
+ async handlePush() {
76
+ if (this.tickInFlight || !this.context)
77
+ return;
78
+ try {
79
+ await this.reconcile(this.context);
80
+ this.callbacks.onTick('online', new Date().toISOString());
81
+ }
82
+ catch (err) {
83
+ this.callbacks.onLog(`[sync] push reconcile failed: ${err}`);
84
+ }
85
+ }
86
+ async reportScreensIfChanged(ctx) {
87
+ const screens = await (0, index_1.listScreens)();
88
+ if (screens.length === 0)
89
+ return;
90
+ const fp = (0, index_1.fingerprintScreens)(screens);
91
+ if (fp === this.lastScreensFingerprint)
92
+ return;
93
+ try {
94
+ await this.api.reportDeviceScreens(ctx.token, ctx.deviceId, screens);
95
+ this.lastScreensFingerprint = fp;
96
+ }
97
+ catch (err) {
98
+ this.callbacks.onLog(`[sync] reportScreens failed: ${err}`);
99
+ }
100
+ }
101
+ async fetchCommands(ctx) {
102
+ try {
103
+ const commands = await this.api.getDeviceCommands(ctx.token, ctx.deviceId);
104
+ for (const cmd of commands) {
105
+ this.callbacks.onLog(`[sync] command ${cmd.type} (${cmd.id})`);
106
+ }
107
+ this.callbacks.onTick('online', new Date().toISOString());
108
+ }
109
+ catch {
110
+ this.callbacks.onTick('error');
111
+ }
112
+ }
113
+ async reconcile(ctx) {
114
+ let assignments;
115
+ try {
116
+ assignments = await this.api.getDeviceScreenAssignments(ctx.token, ctx.deviceId);
117
+ }
118
+ catch (err) {
119
+ this.callbacks.onLog(`[sync] getAssignments failed: ${err}`);
120
+ return;
121
+ }
122
+ const screens = await (0, index_1.listScreens)();
123
+ const keepIds = [...new Set(assignments.map(a => a.wallpaperId).filter((id) => !!id))];
124
+ await Promise.all(assignments.map(async (assignment) => {
125
+ if (!assignment.imageUrl || !assignment.wallpaperId)
126
+ return;
127
+ if (this.applied.get(assignment.stableId) === assignment.wallpaperId)
128
+ return;
129
+ try {
130
+ const imageUrl = this.api.absoluteImageUrl(assignment.imageUrl);
131
+ const localPath = await (0, cache_1.ensureWallpaper)(assignment.wallpaperId, imageUrl, assignment.mimeType);
132
+ await (0, index_2.applyWallpaper)(localPath, assignment.stableId, screens);
133
+ this.applied.set(assignment.stableId, assignment.wallpaperId);
134
+ await this.api.acknowledgeApplied(ctx.token, ctx.deviceId, assignment.stableId, assignment.wallpaperId);
135
+ this.callbacks.onLog(`[sync] applied wallpaper ${assignment.wallpaperId} → ${assignment.stableId}`);
136
+ }
137
+ catch (err) {
138
+ this.callbacks.onLog(`[sync] apply failed for ${assignment.stableId}: ${err}`);
139
+ }
140
+ }));
141
+ await (0, cache_1.pruneCache)(keepIds);
142
+ }
143
+ }
144
+ exports.SyncService = SyncService;
@@ -0,0 +1,10 @@
1
+ export interface DeviceIdentity {
2
+ deviceId: string;
3
+ deviceName: string;
4
+ }
5
+ export declare function getDeviceToken(): Promise<string | null>;
6
+ export declare function setDeviceToken(token: string): Promise<void>;
7
+ export declare function deleteDeviceToken(): Promise<void>;
8
+ export declare function getDeviceIdentity(): Promise<DeviceIdentity | null>;
9
+ export declare function setDeviceIdentity(identity: DeviceIdentity): Promise<void>;
10
+ export declare function clearDeviceIdentity(): Promise<void>;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getDeviceToken = getDeviceToken;
37
+ exports.setDeviceToken = setDeviceToken;
38
+ exports.deleteDeviceToken = deleteDeviceToken;
39
+ exports.getDeviceIdentity = getDeviceIdentity;
40
+ exports.setDeviceIdentity = setDeviceIdentity;
41
+ exports.clearDeviceIdentity = clearDeviceIdentity;
42
+ const fs = __importStar(require("node:fs/promises"));
43
+ const path = __importStar(require("node:path"));
44
+ const os = __importStar(require("node:os"));
45
+ const KEYTAR_SERVICE = 'walldock-agent';
46
+ const KEYTAR_ACCOUNT = 'device-token';
47
+ function configDir() {
48
+ if (process.platform === 'win32') {
49
+ return path.join(process.env['APPDATA'] ?? os.homedir(), 'walldock');
50
+ }
51
+ if (process.platform === 'darwin') {
52
+ return path.join(os.homedir(), 'Library', 'Application Support', 'walldock');
53
+ }
54
+ return path.join(process.env['XDG_CONFIG_HOME'] ?? path.join(os.homedir(), '.config'), 'walldock');
55
+ }
56
+ const CONFIG_FILE = path.join(configDir(), 'auth.json');
57
+ async function readAuthFile() {
58
+ try {
59
+ const raw = await fs.readFile(CONFIG_FILE, 'utf8');
60
+ return JSON.parse(raw);
61
+ }
62
+ catch {
63
+ return {};
64
+ }
65
+ }
66
+ async function writeAuthFile(data) {
67
+ await fs.mkdir(path.dirname(CONFIG_FILE), { recursive: true });
68
+ await fs.writeFile(CONFIG_FILE, JSON.stringify(data, null, 2), { mode: 0o600 });
69
+ }
70
+ async function tryKeytar() {
71
+ try {
72
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
73
+ return require('keytar');
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ async function getDeviceToken() {
80
+ const keytar = await tryKeytar();
81
+ if (keytar) {
82
+ try {
83
+ const token = await keytar.getPassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT);
84
+ if (token)
85
+ return token;
86
+ }
87
+ catch {
88
+ // fall through to file
89
+ }
90
+ }
91
+ const auth = await readAuthFile();
92
+ return auth.deviceToken ?? null;
93
+ }
94
+ async function setDeviceToken(token) {
95
+ const keytar = await tryKeytar();
96
+ if (keytar) {
97
+ try {
98
+ await keytar.setPassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT, token);
99
+ // also write identity file (without token) so offline boot still works
100
+ const auth = await readAuthFile();
101
+ delete auth.deviceToken;
102
+ await writeAuthFile(auth);
103
+ return;
104
+ }
105
+ catch {
106
+ // fall through to file
107
+ }
108
+ }
109
+ const auth = await readAuthFile();
110
+ auth.deviceToken = token;
111
+ await writeAuthFile(auth);
112
+ }
113
+ async function deleteDeviceToken() {
114
+ const keytar = await tryKeytar();
115
+ if (keytar) {
116
+ try {
117
+ await keytar.deletePassword(KEYTAR_SERVICE, KEYTAR_ACCOUNT);
118
+ }
119
+ catch { /* ok */ }
120
+ }
121
+ const auth = await readAuthFile();
122
+ delete auth.deviceToken;
123
+ await writeAuthFile(auth);
124
+ }
125
+ async function getDeviceIdentity() {
126
+ const auth = await readAuthFile();
127
+ if (!auth.deviceId || !auth.deviceName)
128
+ return null;
129
+ return { deviceId: auth.deviceId, deviceName: auth.deviceName };
130
+ }
131
+ async function setDeviceIdentity(identity) {
132
+ const auth = await readAuthFile();
133
+ auth.deviceId = identity.deviceId;
134
+ auth.deviceName = identity.deviceName;
135
+ await writeAuthFile(auth);
136
+ }
137
+ async function clearDeviceIdentity() {
138
+ const auth = await readAuthFile();
139
+ delete auth.deviceId;
140
+ delete auth.deviceName;
141
+ await writeAuthFile(auth);
142
+ }
@@ -0,0 +1,2 @@
1
+ import type { Screen } from '../screens/index';
2
+ export declare function applyWallpaper(imagePath: string, stableId: string, screens: Screen[]): Promise<void>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.applyWallpaper = applyWallpaper;
37
+ async function applyWallpaper(imagePath, stableId, screens) {
38
+ const index = screens.findIndex(s => s.stableId === stableId);
39
+ if (index === -1)
40
+ throw new Error(`No screen found for stableId ${stableId}`);
41
+ if (process.platform === 'darwin') {
42
+ const { setWallpaperMacOS } = await Promise.resolve().then(() => __importStar(require('./macos')));
43
+ return setWallpaperMacOS(imagePath, index);
44
+ }
45
+ if (process.platform === 'win32') {
46
+ const { setWallpaperWindows } = await Promise.resolve().then(() => __importStar(require('./windows')));
47
+ return setWallpaperWindows(imagePath, index);
48
+ }
49
+ const { setWallpaperLinux } = await Promise.resolve().then(() => __importStar(require('./linux')));
50
+ return setWallpaperLinux(imagePath, index, screens.length);
51
+ }
@@ -0,0 +1 @@
1
+ export declare function setWallpaperLinux(imagePath: string, monitorIndex: number, totalMonitors: number): Promise<void>;