@glassnote/client 2.4.8 → 2.4.9
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/autoStart.js +21 -49
- package/bin/glassnote.js +23 -5
- package/package.json +4 -2
package/autoStart.js
CHANGED
|
@@ -220,35 +220,6 @@ class AutoStart {
|
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
// Remove existing plist if it exists
|
|
224
|
-
if (fs.existsSync(plistPath)) {
|
|
225
|
-
try {
|
|
226
|
-
// Use spawn instead of execSync to avoid blocking
|
|
227
|
-
const unloadProcess = spawn('launchctl', ['unload', plistPath], {
|
|
228
|
-
stdio: 'ignore',
|
|
229
|
-
timeout: 5000 // 5 second timeout
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
unloadProcess.on('error', (error) => {
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
unloadProcess.on('exit', (code) => {
|
|
236
|
-
if (code !== 0) {
|
|
237
|
-
console.warn('launchctl unload exited with code:', code, '(may not be loaded)');
|
|
238
|
-
}
|
|
239
|
-
});
|
|
240
|
-
} catch (error) {
|
|
241
|
-
console.error('Could not unload existing plist:', error.message);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Remove the plist file regardless of launchctl status
|
|
245
|
-
try {
|
|
246
|
-
fs.unlinkSync(plistPath);
|
|
247
|
-
} catch (error) {
|
|
248
|
-
console.error('Could not remove plist file:', error.message);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
223
|
const plistContent = `<?xml version="1.0" encoding="UTF-8"?>
|
|
253
224
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
254
225
|
<plist version="1.0">
|
|
@@ -273,29 +244,30 @@ ${launchArgs.map((a) => ` <string>${a}</string>`).join('\n')}
|
|
|
273
244
|
fs.mkdirSync(plistDir, { recursive: true });
|
|
274
245
|
}
|
|
275
246
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
//
|
|
247
|
+
// El plist NO se borra ni se recarga si ya dice lo mismo, y NUNCA se hace
|
|
248
|
+
// `launchctl unload`.
|
|
249
|
+
//
|
|
250
|
+
// Esto lo llama el main en CADA arranque. En macOS, cuando el que arranca es el
|
|
251
|
+
// propio LaunchAgent (o sea: al iniciar sesión, que es el caso normal), la app era
|
|
252
|
+
// el job de launchd: el `launchctl unload` de aquí abajo mataba el job, y con él a
|
|
253
|
+
// la app que lo estaba ejecutando. Medido: el cliente se abría al login y se moría
|
|
254
|
+
// a los ~3 segundos, antes incluso del primer chequeo de actualización, que es a
|
|
255
|
+
// los 5. Encima el agente quedaba descargado, así que ni `launchctl list` lo veía.
|
|
256
|
+
//
|
|
257
|
+
// Tampoco se hace `load` cuando el contenido cambia: `RunAtLoad` arrancaría OTRA
|
|
258
|
+
// instancia encima de esta —la app no tiene lock de instancia única— y el archivo
|
|
259
|
+
// nuevo lo lee launchd solo en el próximo login, que es justo cuando tiene que
|
|
260
|
+
// valer. Escribirlo es todo lo que hace falta.
|
|
261
|
+
let actual = null;
|
|
279
262
|
try {
|
|
280
|
-
|
|
281
|
-
stdio: 'ignore',
|
|
282
|
-
timeout: 5000 // 5 second timeout
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
loadProcess.on('error', (error) => {
|
|
286
|
-
console.error('Error spawning launchctl load:', error.message);
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
loadProcess.on('exit', (code) => {
|
|
290
|
-
if (code !== 0) {
|
|
291
|
-
console.warn('launchctl load exited with code:', code);
|
|
292
|
-
} else {
|
|
293
|
-
console.warn('macOS auto-start configured:', plistPath);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
263
|
+
actual = fs.readFileSync(plistPath, 'utf8');
|
|
296
264
|
} catch (error) {
|
|
297
|
-
|
|
265
|
+
actual = null; // no existía
|
|
298
266
|
}
|
|
267
|
+
if (actual === plistContent) return true;
|
|
268
|
+
|
|
269
|
+
fs.writeFileSync(plistPath, plistContent);
|
|
270
|
+
console.log('macOS auto-start configured:', plistPath);
|
|
299
271
|
|
|
300
272
|
return true;
|
|
301
273
|
} catch (error) {
|
package/bin/glassnote.js
CHANGED
|
@@ -52,14 +52,26 @@ function npmEnv() {
|
|
|
52
52
|
// con otro entorno, y ahí `npm` no existe. La auto-actualización moría en "npm no se
|
|
53
53
|
// reconoce como un comando" y nadie lo veía. Si no hay forma de resolver el npm-cli.js se
|
|
54
54
|
// vuelve al shim de siempre.
|
|
55
|
-
|
|
55
|
+
// Separado de runNpm a propósito: decidir CÓMO se llama a npm es una función pura, y por
|
|
56
|
+
// eso se puede comprobar en cualquier sistema (scripts/test-update.js lo hace). Ejecutarlo
|
|
57
|
+
// no. La regresión que hay que impedir es volver a `shell: true` con un array de
|
|
58
|
+
// argumentos: Node no entrecomilla en ese caso y en Windows la ruta del prefix se parte en
|
|
59
|
+
// el primer espacio —`C:\Users\Santiago Andrade\...`—, con lo que npm intenta un
|
|
60
|
+
// mkdir de 'C:\Users\Santiago' y la instalación entera falla con EPERM.
|
|
61
|
+
function npmInvocation(args) {
|
|
56
62
|
const nodeBinary = mode.resolveNodeBinary(process.execPath);
|
|
57
63
|
const npmCli = mode.resolveNpmCli(nodeBinary);
|
|
58
|
-
const base = { stdio: 'inherit', shell: false, env: npmEnv() };
|
|
59
64
|
if (nodeBinary && npmCli) {
|
|
60
|
-
return
|
|
65
|
+
return { file: nodeBinary, args: [npmCli].concat(args), shell: false, viaNode: true };
|
|
61
66
|
}
|
|
62
|
-
|
|
67
|
+
// Sin npm-cli.js localizable no queda más que el shim del PATH. Sigue sin shell:
|
|
68
|
+
// spawnSync con un array ya entrecomilla por su cuenta cuando no hay shell de por medio.
|
|
69
|
+
return { file: NPM_CMD, args, shell: false, viaNode: false };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function runNpm(args, opts) {
|
|
73
|
+
const { file, args: argv, shell } = npmInvocation(args);
|
|
74
|
+
return spawnSync(file, argv, Object.assign({ stdio: 'inherit', shell, env: npmEnv() }, opts || {}));
|
|
63
75
|
}
|
|
64
76
|
|
|
65
77
|
// userData tira de `uuid`, y este CLI corre también donde el árbol de dependencias no
|
|
@@ -772,4 +784,10 @@ function main() {
|
|
|
772
784
|
}
|
|
773
785
|
}
|
|
774
786
|
|
|
775
|
-
|
|
787
|
+
// Requerido desde un test, el archivo NO debe correr nada: solo expone las piezas que
|
|
788
|
+
// se comprueban. Como CLI se comporta igual que siempre.
|
|
789
|
+
if (require.main === module) {
|
|
790
|
+
process.exit(main());
|
|
791
|
+
} else {
|
|
792
|
+
module.exports = { npmInvocation, npmEnv, toSpec };
|
|
793
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassnote/client",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.9",
|
|
4
4
|
"description": "GlassNote — cliente de escritorio de notas superpuestas. Se instala con npx, sin instaladores nativos ni firmas.",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -51,7 +51,9 @@
|
|
|
51
51
|
"sync-installers": "node scripts/sync-installers.js",
|
|
52
52
|
"local-registry": "node scripts/local-registry.js",
|
|
53
53
|
"prepublishOnly": "node scripts/check-publish.js",
|
|
54
|
-
"start-electron": "electron ."
|
|
54
|
+
"start-electron": "electron .",
|
|
55
|
+
"test-update": "node scripts/test-update.js",
|
|
56
|
+
"test": "node scripts/test-update.js"
|
|
55
57
|
},
|
|
56
58
|
"keywords": [
|
|
57
59
|
"glassnote",
|