kitowall 3.5.12 → 3.5.13
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/core/init.js +93 -10
- package/package.json +1 -1
package/dist/core/init.js
CHANGED
|
@@ -16,6 +16,87 @@ function esc(a) {
|
|
|
16
16
|
// ExecStart=... necesita escapado simple. JSON.stringify funciona bien para espacios/comillas.
|
|
17
17
|
return JSON.stringify(a);
|
|
18
18
|
}
|
|
19
|
+
async function runHostShell(cmd) {
|
|
20
|
+
if (process.env.FLATPAK_ID) {
|
|
21
|
+
return (0, exec_1.run)('flatpak-spawn', ['--host', 'sh', '-lc', cmd]);
|
|
22
|
+
}
|
|
23
|
+
return (0, exec_1.run)('sh', ['-lc', cmd]);
|
|
24
|
+
}
|
|
25
|
+
async function hostCmdExists(cmd) {
|
|
26
|
+
try {
|
|
27
|
+
await runHostShell(`command -v ${cmd} >/dev/null 2>&1`);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function ensureHostDeps() {
|
|
35
|
+
const required = ['swww', 'swww-daemon', 'hyprctl', 'mpvpaper'];
|
|
36
|
+
const missing = [];
|
|
37
|
+
for (const dep of required) {
|
|
38
|
+
if (!(await hostCmdExists(dep)))
|
|
39
|
+
missing.push(dep);
|
|
40
|
+
}
|
|
41
|
+
if (missing.length === 0)
|
|
42
|
+
return;
|
|
43
|
+
const pkgSet = new Set();
|
|
44
|
+
if (missing.includes('swww') || missing.includes('swww-daemon'))
|
|
45
|
+
pkgSet.add('swww');
|
|
46
|
+
if (missing.includes('hyprctl'))
|
|
47
|
+
pkgSet.add('hyprland');
|
|
48
|
+
if (missing.includes('mpvpaper'))
|
|
49
|
+
pkgSet.add('mpvpaper');
|
|
50
|
+
const packages = Array.from(pkgSet);
|
|
51
|
+
// Best effort auto-install on Arch host; if it fails, we keep a clear actionable error.
|
|
52
|
+
if (packages.length > 0 && await hostCmdExists('pacman')) {
|
|
53
|
+
const pkgArgs = packages.join(' ');
|
|
54
|
+
await runHostShell(`if command -v sudo >/dev/null 2>&1; then ` +
|
|
55
|
+
`(sudo -n pacman -S --needed --noconfirm ${pkgArgs} || sudo pacman -S --needed ${pkgArgs}); ` +
|
|
56
|
+
`else pacman -S --needed ${pkgArgs}; fi`).catch(() => { });
|
|
57
|
+
}
|
|
58
|
+
const stillMissing = [];
|
|
59
|
+
for (const dep of required) {
|
|
60
|
+
if (!(await hostCmdExists(dep)))
|
|
61
|
+
stillMissing.push(dep);
|
|
62
|
+
}
|
|
63
|
+
if (stillMissing.length > 0) {
|
|
64
|
+
throw new Error(`Missing host dependencies: ${stillMissing.join(', ')}. ` +
|
|
65
|
+
`Install on host (Arch): sudo pacman -S --needed swww hyprland mpvpaper`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function ensureHostRendercoreBridge(appId) {
|
|
69
|
+
const home = (0, node_os_1.homedir)();
|
|
70
|
+
const localBinDir = (0, node_path_1.join)(home, '.local', 'bin');
|
|
71
|
+
ensureDir(localBinDir);
|
|
72
|
+
const bridgePath = (0, node_path_1.join)(localBinDir, 'kitsune-rendercore');
|
|
73
|
+
const bridgeScript = `#!/usr/bin/env bash
|
|
74
|
+
set -euo pipefail
|
|
75
|
+
exec /usr/bin/flatpak run --command=kitsune-rendercore ${appId} "$@"
|
|
76
|
+
`;
|
|
77
|
+
(0, node_fs_1.writeFileSync)(bridgePath, bridgeScript, { encoding: 'utf8', mode: 0o755 });
|
|
78
|
+
const userDir = (0, node_path_1.join)(home, '.config', 'systemd', 'user');
|
|
79
|
+
ensureDir(userDir);
|
|
80
|
+
const unitPath = (0, node_path_1.join)(userDir, 'kitsune-rendercore.service');
|
|
81
|
+
const unit = `
|
|
82
|
+
[Unit]
|
|
83
|
+
Description=Kitsune RenderCore Live Wallpaper (Flatpak bridge)
|
|
84
|
+
After=graphical-session.target
|
|
85
|
+
PartOf=graphical-session.target
|
|
86
|
+
|
|
87
|
+
[Service]
|
|
88
|
+
Type=simple
|
|
89
|
+
ExecStart=${bridgePath}
|
|
90
|
+
Restart=on-failure
|
|
91
|
+
RestartSec=1
|
|
92
|
+
|
|
93
|
+
[Install]
|
|
94
|
+
WantedBy=default.target
|
|
95
|
+
`.trimStart();
|
|
96
|
+
(0, node_fs_1.writeFileSync)(unitPath, unit, 'utf8');
|
|
97
|
+
await (0, exec_1.run)('systemctl', ['--user', 'daemon-reload']);
|
|
98
|
+
await (0, exec_1.run)('systemctl', ['--user', 'enable', '--now', 'kitsune-rendercore.service']).catch(() => { });
|
|
99
|
+
}
|
|
19
100
|
async function disableIfExists(unit) {
|
|
20
101
|
await (0, exec_1.run)('systemctl', ['--user', 'disable', '--now', unit]).catch(() => { });
|
|
21
102
|
await (0, exec_1.run)('systemctl', ['--user', 'reset-failed', unit]).catch(() => { });
|
|
@@ -39,24 +120,26 @@ async function detectAndHandleConflicts(force) {
|
|
|
39
120
|
}
|
|
40
121
|
}
|
|
41
122
|
async function initKitowall(opts) {
|
|
42
|
-
if (process.env.FLATPAK_ID) {
|
|
43
|
-
throw new Error('init/repair cannot be executed from Flatpak UI because it would generate host systemd units with sandbox paths. ' +
|
|
44
|
-
'Run on host shell: kitowall init --namespace kitowall --apply --force (or, in local dev, node dist/cli.js init --namespace kitowall --apply --force)');
|
|
45
|
-
}
|
|
46
123
|
const config = (0, config_1.loadConfig)(); // crea/migra config si hace falta
|
|
47
124
|
const state = (0, state_1.loadState)(); // crea/migra state si hace falta
|
|
48
125
|
const ns = (opts.namespace && opts.namespace.trim()) ? opts.namespace.trim() : 'kitowall';
|
|
49
126
|
const force = !!opts.force;
|
|
127
|
+
const isFlatpak = Boolean(process.env.FLATPAK_ID);
|
|
128
|
+
const flatpakAppId = (process.env.FLATPAK_ID || 'io.kitotsu.KitoWall').trim();
|
|
50
129
|
// Validaciones mínimas
|
|
51
|
-
await (
|
|
52
|
-
|
|
53
|
-
|
|
130
|
+
await ensureHostDeps();
|
|
131
|
+
if (isFlatpak) {
|
|
132
|
+
await ensureHostRendercoreBridge(flatpakAppId);
|
|
133
|
+
}
|
|
54
134
|
// Apagar servicios que pisan el wallpaper
|
|
55
135
|
await detectAndHandleConflicts(force);
|
|
56
136
|
const userDir = (0, node_path_1.join)((0, node_os_1.homedir)(), '.config', 'systemd', 'user');
|
|
57
137
|
ensureDir(userDir);
|
|
58
138
|
const nodePath = process.execPath;
|
|
59
139
|
const cliPath = (0, node_path_1.resolve)(process.argv[1]); // dist/cli.js absoluto
|
|
140
|
+
const cliInvoke = isFlatpak
|
|
141
|
+
? `/usr/bin/flatpak run --command=kitowall ${flatpakAppId}`
|
|
142
|
+
: `${JSON.stringify(nodePath)} ${JSON.stringify(cliPath)}`;
|
|
60
143
|
const xdgRuntimeDir = (process.env.XDG_RUNTIME_DIR && process.env.XDG_RUNTIME_DIR.trim())
|
|
61
144
|
? process.env.XDG_RUNTIME_DIR.trim()
|
|
62
145
|
: `/run/user/${process.getuid?.() ?? 1000}`;
|
|
@@ -92,7 +175,7 @@ WantedBy=graphical-session.target
|
|
|
92
175
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(userDir, 'swww-daemon@.service'), swwwDaemonTemplate, 'utf8');
|
|
93
176
|
// 2) kitowall-next.service (oneshot)
|
|
94
177
|
// OJO: aunque CLI ignore --namespace en algunos comandos, aquí lo dejamos por compatibilidad.
|
|
95
|
-
const nextExec = `/bin/sh -lc ${esc(`${waylandBootstrap} exec ${
|
|
178
|
+
const nextExec = `/bin/sh -lc ${esc(`${waylandBootstrap} exec ${cliInvoke} next --namespace ${JSON.stringify(ns)}`)}`;
|
|
96
179
|
const kitowallNextService = `
|
|
97
180
|
[Unit]
|
|
98
181
|
Description=Kitowall apply next wallpapers
|
|
@@ -107,7 +190,7 @@ ExecStart=${nextExec}
|
|
|
107
190
|
`.trimStart();
|
|
108
191
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(userDir, 'kitowall-next.service'), kitowallNextService, 'utf8');
|
|
109
192
|
// 3) kitowall-watch.service (hotplug watcher)
|
|
110
|
-
const watchExec = `/bin/sh -lc ${esc(`${waylandBootstrap} exec ${
|
|
193
|
+
const watchExec = `/bin/sh -lc ${esc(`${waylandBootstrap} exec ${cliInvoke} watch --namespace ${JSON.stringify(ns)}`)}`;
|
|
111
194
|
const kitowallWatchService = `
|
|
112
195
|
[Unit]
|
|
113
196
|
Description=Kitowall watcher (monitor hotplug)
|
|
@@ -128,7 +211,7 @@ WantedBy=graphical-session.target
|
|
|
128
211
|
`.trimStart();
|
|
129
212
|
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(userDir, 'kitowall-watch.service'), kitowallWatchService, 'utf8');
|
|
130
213
|
// 4) kitowall-login-apply.service (apply once on login to avoid gray background)
|
|
131
|
-
const loginApplyExec = `/bin/sh -lc ${esc(`sleep 2; ${waylandBootstrap} exec ${
|
|
214
|
+
const loginApplyExec = `/bin/sh -lc ${esc(`sleep 2; ${waylandBootstrap} exec ${cliInvoke} rotate-now --namespace ${JSON.stringify(ns)} --force`)}`;
|
|
132
215
|
const kitowallLoginApplyService = `
|
|
133
216
|
[Unit]
|
|
134
217
|
Description=Kitowall apply wallpapers on session start
|