From 97d6667e76f5491e80195ef0ab9e12c4d59c6b91 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 06:39:32 +0000 Subject: [PATCH 1/2] Fix installed app crashing at startup: package zip.js The 1.3.0 installers died on launch with ERR_MODULE_NOT_FOUND for 'app.asar/zip.js'. electron-builder's "files" field is an allowlist that named main.js, preload.cjs and latex.js one by one, so zip.js -- added in 1.3.0 and imported by main.js -- was never packaged. Running from source worked, which is why nothing caught it. The list now uses "*.js", so a new top-level module is included on its own rather than depending on someone remembering this file. Also adds verifica-pacchetto.mjs, run by CI and by the release workflow: it walks the main-process imports from main.js and preload.cjs and fails if any of them is missing from the built app.asar. The existing smoke test launches the app from the source directory, where every module is present by construction, so it could not see the gap between sources and package -- which is exactly how a broken installer got published. --- .github/workflows/ci.yml | 7 ++++ .github/workflows/release.yml | 10 +++++ CHANGELOG.md | 14 +++++++ desktop/package-lock.json | 4 +- desktop/package.json | 5 +-- desktop/verifica-pacchetto.mjs | 74 ++++++++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 desktop/verifica-pacchetto.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 545e2f4..d45aebe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,6 +117,13 @@ jobs: test -x "$f" || { echo "$f non eseguibile"; exit 1; } ls -lh "$f" + # Lo smoke test qui sopra gira sui sorgenti, dove i moduli ci sono + # sempre: non può accorgersi di un file dimenticato nella allowlist + # `files`. Questo controlla il pacchetto vero. + - name: Il pacchetto contiene tutti i moduli del processo principale + working-directory: desktop + run: node verifica-pacchetto.mjs ../dist-desktop/linux-unpacked/resources/app.asar + portatile: name: Versione portatile in file singolo runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5f5ad72..f5159e5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,6 +50,16 @@ jobs: working-directory: desktop run: ${{ matrix.comando }} + - name: Il pacchetto contiene tutti i moduli del processo principale + shell: bash + working-directory: desktop + run: | + # Una dimenticanza nella allowlist `files` non rompe i sorgenti, solo + # l'app installata: va intercettata prima di pubblicare gli installer. + asar=$(find ../dist-desktop -name app.asar -print -quit) + test -n "$asar" || { echo "app.asar non trovato sotto dist-desktop"; exit 1; } + node verifica-pacchetto.mjs "$asar" + - name: Elenca i file prodotti shell: bash run: ls -lh dist-desktop/ || dir dist-desktop diff --git a/CHANGELOG.md b/CHANGELOG.md index 4de3c5e..ce21e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [1.3.1] + +### Corretto +- **L'app installata non partiva più.** All'avvio moriva con + `ERR_MODULE_NOT_FOUND: Cannot find module '…app.asar/zip.js'`: la lista + `files` di electron-builder è una allowlist e `zip.js`, aggiunto nella + 1.3.0 per il download in ZIP, non era stato elencato. Restava quindi fuori + dal pacchetto, pur essendo importato da `main.js`. Ora la lista usa `*.js`, + così un modulo nuovo è incluso da sé. +- La CI e la release verificano che l'archivio contenga davvero ogni modulo + importato dal processo principale (`verifica-pacchetto.mjs`). Lo smoke test + esistente gira sui sorgenti, dove i file ci sono sempre: non poteva + accorgersi di questa differenza fra sorgenti e pacchetto. + ## [1.3.0] ### Aggiunto diff --git a/desktop/package-lock.json b/desktop/package-lock.json index 05c86ca..c25c9c9 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -1,12 +1,12 @@ { "name": "texforge-desktop", - "version": "1.2.0", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "texforge-desktop", - "version": "1.2.0", + "version": "1.3.1", "license": "MIT", "dependencies": { "@pdf-lib/fontkit": "^1.1.1", diff --git a/desktop/package.json b/desktop/package.json index a32fadc..47d9121 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,7 +1,7 @@ { "name": "texforge-desktop", "productName": "texforge", - "version": "1.3.0", + "version": "1.3.1", "description": "Compilatore LaTeX in PDF statico e HTML interattivo, con gestione dei pacchetti", "type": "module", "main": "main.js", @@ -35,9 +35,8 @@ "buildResources": "risorse" }, "files": [ - "main.js", + "*.js", "preload.cjs", - "latex.js", "renderer/**", "vendor/**", "!**/*.map" diff --git a/desktop/verifica-pacchetto.mjs b/desktop/verifica-pacchetto.mjs new file mode 100644 index 0000000..f89d577 --- /dev/null +++ b/desktop/verifica-pacchetto.mjs @@ -0,0 +1,74 @@ +// --------------------------------------------------------------------------- +// Verifica che l'archivio prodotto da electron-builder contenga davvero tutti +// i moduli locali che il processo principale importa. +// +// node verifica-pacchetto.mjs ../dist-desktop/linux-unpacked/resources/app.asar +// +// La lista `files` in package.json è una allowlist: un modulo nuovo che non +// viene aggiunto lì resta fuori dal pacchetto. I sorgenti continuano a +// funzionare e lo smoke test — che gira sui sorgenti — non se ne accorge; +// l'app installata invece muore all'avvio con ERR_MODULE_NOT_FOUND. È +// successo con zip.js nella 1.3.0, e questo controllo serve a non ripeterlo. +// --------------------------------------------------------------------------- + +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { listPackage } from '@electron/asar'; + +const QUI = path.dirname(fileURLToPath(import.meta.url)); + +const archivio = process.argv[2]; +if (!archivio) { + console.error('uso: node verifica-pacchetto.mjs '); + process.exit(2); +} +if (!fs.existsSync(archivio)) { + console.error(`archivio non trovato: ${archivio}`); + process.exit(2); +} + +// listPackage restituisce percorsi con lo slash iniziale ('/main.js'), e su +// Windows con le barre rovesciate: normalizziamo per poterli confrontare. +const dentro = new Set( + listPackage(archivio, { isPack: false }) + .map((v) => v.replace(/\\/g, '/').replace(/^\//, '')) +); + +// Partiamo dai due punti d'ingresso e seguiamo gli import locali a cascata: +// così un modulo raggiunto solo indirettamente viene controllato comunque. +const daVedere = ['main.js', 'preload.cjs']; +const visti = new Set(); +const mancanti = []; + +while (daVedere.length) { + const modulo = daVedere.pop(); + if (visti.has(modulo)) continue; + visti.add(modulo); + + if (!dentro.has(modulo)) { + mancanti.push(modulo); + // Non è nel pacchetto: i suoi import li leggiamo comunque dai sorgenti, + // per segnalare in un colpo solo tutta la catena che manca. + } + + const sorgente = path.join(QUI, modulo); + if (!fs.existsSync(sorgente)) continue; + const testo = fs.readFileSync(sorgente, 'utf-8'); + + for (const trovato of [ + ...testo.matchAll(/(?:from|import)\s+['"](\.[^'"]+)['"]/g), + ...testo.matchAll(/require\(\s*['"](\.[^'"]+)['"]\s*\)/g), + ]) { + // I riferimenti sono relativi al modulo che li contiene, non alla radice. + daVedere.push(path.posix.normalize(path.posix.join(path.posix.dirname(modulo), trovato[1]))); + } +} + +if (mancanti.length) { + console.error(`moduli assenti da ${path.basename(archivio)}: ${mancanti.join(', ')}`); + console.error('aggiungili alla lista "files" in desktop/package.json'); + process.exit(1); +} + +console.log(`${visti.size} moduli del processo principale presenti nell'archivio`); diff --git a/package.json b/package.json index 6734858..5a65a0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "texforge", - "version": "1.3.0", + "version": "1.3.1", "description": "Sito di presentazione e strumenti di build di texforge", "type": "module", "main": "server.js", From 433ca76939cb889d0193c2d163973d200bf8da9d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 10 Aug 2026 06:58:56 +0000 Subject: [PATCH 2/2] Rewrite the Pages site: current content, editorial design The site still described a workflow that no longer exists. It told visitors to upload .tex files so "the backend compiles" and returns the results -- but the compiler was removed from the web in 1.2.0 and now lives only in the desktop app. The footer likewise credited an "Express backend" that today just serves these static pages. Content, rewritten around the app that actually ships: - what the three screens do, including the new one-ZIP-per-format download and the sandboxed HTML preview - how the LaTeX engine is found or installed: TinyTeX into the user's own folder with no admin rights, then 31 base packages and 19 TeX Live collections, and what is deliberately left out - the Pacchetti page mapped to the tlmgr commands behind it - every quizstruct command with its real signature, checked against the .sty, and what each one becomes in the PDF versus the HTML - when network access is needed, and that sources never leave the machine Design: system fonts only (no remote requests), serif headings, one green accent, and a dark palette via prefers-color-scheme. Dropped the emoji step icons, the 01-06 section counters, the decorative glow and the scroll-triggered fade-ins. The hero now shows one source fragment beside its two renderings, so the page demonstrates the product rather than asserting it. Tables replace card grids where the content is genuinely tabular. Verified in Chromium: no horizontal overflow at 12 widths from 320px to 1600px, light and dark, no console errors, one h1 with no skipped heading levels, working tabs and mobile menu. --- docs/index.html | 1059 +++++++++++++++++++++++------------------- docs/script.js | 247 +++++----- docs/style.css | 1172 ++++++++++++++++++----------------------------- 3 files changed, 1149 insertions(+), 1329 deletions(-) diff --git a/docs/index.html b/docs/index.html index dcde822..d450414 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,552 +3,689 @@ - tex⟶ texforge — documentazione - - + texforge — documentazione + + + -
- -