From 524ccd708a239f171eb68e96f7cb558364d99af2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 16:58:02 +0000 Subject: [PATCH 1/2] File audit + one-file installer bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit: only one file in the repo wasn't earning its keep — assets/icon-preview-256.png was generated once for documentation and never used by build or runtime. Removed. Everything else (cli.mjs, lib/* x11, print-files.ps1, config.example.json, assets/icon.{svg,ico}, scripts/build.mjs, .github/workflows/release.yml) has a clear role and stays. Installer bundle: - scripts/build.mjs now also writes dist/INSTALL.txt — plain-text step-by-step install guide + command reference, so anyone who unzips the bundle has everything they need on paper without internet. - .github/workflows/release.yml zips dist/ into mailpress-installer.zip (PowerShell Compress-Archive) and attaches it to both the workflow artifact and the GitHub Release. One-click download: unzip, double-click mailpress.exe, done. - README's "Install" section updated to point at the single mailpress-installer.zip and shows the file tree of what's inside. https://claude.ai/code/session_01CfsRS2PZ4t8RUnhPdVEWHF --- .github/workflows/release.yml | 14 +++++++++ README.md | 29 ++++++++++++------ assets/icon-preview-256.png | Bin 7042 -> 0 bytes scripts/build.mjs | 56 +++++++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 11 deletions(-) delete mode 100644 assets/icon-preview-256.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0a7bfd5..c376497 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,24 +30,38 @@ jobs: - name: build mailpress.exe run: node scripts/build.mjs + - name: zip installer bundle + # Single-file install bundle: unzip, double-click mailpress.exe, done. + shell: pwsh + run: | + Compress-Archive ` + -Path dist/mailpress.exe,dist/print-files.ps1,dist/config.example.json,dist/mailpress.ico,dist/INSTALL.txt ` + -DestinationPath dist/mailpress-installer.zip ` + -Force + - name: upload artifact + # Includes the zip + the loose files so users can grab either form. uses: actions/upload-artifact@v4 with: name: mailpress-windows-x64 path: | + dist/mailpress-installer.zip dist/mailpress.exe dist/print-files.ps1 dist/config.example.json dist/mailpress.ico + dist/INSTALL.txt - name: release (on tag) if: startsWith(github.ref, 'refs/tags/v') uses: softprops/action-gh-release@v2 with: files: | + dist/mailpress-installer.zip dist/mailpress.exe dist/print-files.ps1 dist/config.example.json dist/mailpress.ico + dist/INSTALL.txt draft: false generate_release_notes: true diff --git a/README.md b/README.md index 355e1af..06e2db4 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,25 @@ wired Windows printer. Runs as a Scheduled Task on the office PC. ## Install (the easy way) -1. Download `mailpress.exe`, `print-files.ps1`, and `config.example.json` - from the latest [GitHub Release][releases] (or the artifact of a - `build on windows` workflow run). Put them all in the same folder, - e.g. `C:\mailpress\`. -2. Double-click `mailpress.exe`. The setup wizard runs the first time - there's no config: it lists installed printers, walks you through the - Google OAuth client creation, runs the consent flow in your browser, - picks a polling interval, does a test print, and installs itself as a - Scheduled Task. -3. Done. Send a test email to the office inbox and confirm it prints. +1. Download **`mailpress-installer.zip`** from the latest + [GitHub Release][releases] (or the artifact of a `build on windows` + workflow run if no release is tagged yet). +2. Unzip it on the office PC, e.g. into `C:\mailpress\`. You'll see: + ``` + mailpress.exe ← double-click this + print-files.ps1 + config.example.json + mailpress.ico + INSTALL.txt ← step-by-step install guide + ``` +3. Double-click `mailpress.exe`. The setup wizard runs on first launch: + - picks the printer + - walks through the one-time Google OAuth client creation + - runs the consent flow in your browser + - asks how often to check for new mail + - does a test print + - installs itself as a Scheduled Task +4. Done. Send a test email to the office inbox and confirm it prints. [releases]: https://github.com/turetsky/mailpress/releases diff --git a/assets/icon-preview-256.png b/assets/icon-preview-256.png deleted file mode 100644 index 2c0a5ccf8003e35e69f8c08c8cad7227d8db7830..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7042 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 diff --git a/scripts/build.mjs b/scripts/build.mjs index 518ecda..6e6d79d 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -168,6 +168,59 @@ function copyAssets() { if (existsSync(ico)) copyFileSync(ico, join(DIST, "mailpress.ico")); } +// Drop a plaintext install guide into the bundle so anyone who unzips it +// has the install steps + command list on paper, without needing internet. +function writeInstallTxt() { + const content = `mailpress - Gmail-to-printer relay +=================================== + +INSTALL (Windows, ~5 minutes including the Google OAuth client step): + + 1. Copy this entire folder somewhere stable on the office PC. + Recommended: C:\\mailpress\\ + + 2. Double-click mailpress.exe. + The first run launches the setup wizard. The wizard walks you + through: + - picking the printer + - creating a Google Cloud OAuth client (one-time, in your browser) + - signing in as the office Gmail account + - picking how often to check for new mail + - a test print + - installing itself as a Windows Scheduled Task + + 3. Done. mailpress now polls the office inbox and prints every new + email body + attachments. + +The one part not automated: creating the OAuth client in Google Cloud. +Google requires a human in a browser for that. The wizard prints the +exact URLs and what to paste back. + + +USEFUL COMMANDS (run from a console in this folder): + + mailpress poll forever (or run wizard if not configured) + mailpress --test switch printer, test print any file, change + polling interval - safe with task running + mailpress --doctor run health checks and tell you what is broken + mailpress --consent re-do the OAuth consent if the token dies + mailpress --setup re-run the setup wizard + mailpress --uninstall remove the scheduled task + mailpress --help full command list + + +LOGS + + mailpress.log poll-loop activity + mailpress-setup.log every prompt + response from the wizard + +If anything goes wrong, run "mailpress --doctor" first - it identifies +which subsystem (config, token, Gmail API, printer, scheduled task) +broke and what to do about each. +`; + writeFileSync(join(DIST, "INSTALL.txt"), content); +} + function smokeTest() { console.log("\nSmoke testing --help..."); try { @@ -189,9 +242,10 @@ async function main() { inject(); await embedIcon(); copyAssets(); + writeInstallTxt(); smokeTest(); console.log(`\nDone. Artifacts in ${DIST}:`); - for (const f of [EXE_NAME, "print-files.ps1", "config.example.json", "mailpress.ico"]) { + for (const f of [EXE_NAME, "print-files.ps1", "config.example.json", "mailpress.ico", "INSTALL.txt"]) { if (existsSync(join(DIST, f))) console.log(` ${f}`); } } From c54d04e89f6b259578e5e9900b899a5fef45f27b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 17:01:36 +0000 Subject: [PATCH 2/2] Drop config.example.json + dead exports; trim install bundle to 3 files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit follow-up: config.example.json is never read at runtime. The wizard creates config.local.json from scratch and the only function that ever referenced the example file (examplePath in lib/config.mjs) had no callers. Removed the file and the dead export. Also removed two other dead exports surfaced by the grep: - isConfigured in lib/config.mjs — never called - SCOPES re-export in lib/oauth.mjs — only used internally Install bundle is now down to exactly three files: mailpress.exe (the app + embedded icon) print-files.ps1 (runtime helper; lib/printer.mjs invokes it) INSTALL.txt (paper install guide) Removed from the install bundle: - config.example.json — wizard creates the config; no one needs the template - mailpress.ico — icon already embedded in the exe; the loose .ico only matters if you want to pin a custom shortcut INSTALL.txt updated to list the actual contents + the auto-generated files that appear after the wizard runs. https://claude.ai/code/session_01CfsRS2PZ4t8RUnhPdVEWHF --- .github/workflows/release.yml | 6 +---- README.md | 5 +--- config.example.json | 23 ------------------ lib/config.mjs | 10 -------- lib/oauth.mjs | 2 -- scripts/build.mjs | 46 ++++++++++++++++++----------------- 6 files changed, 26 insertions(+), 66 deletions(-) delete mode 100644 config.example.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c376497..03b5663 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,7 @@ jobs: shell: pwsh run: | Compress-Archive ` - -Path dist/mailpress.exe,dist/print-files.ps1,dist/config.example.json,dist/mailpress.ico,dist/INSTALL.txt ` + -Path dist/mailpress.exe,dist/print-files.ps1,dist/INSTALL.txt ` -DestinationPath dist/mailpress-installer.zip ` -Force @@ -48,8 +48,6 @@ jobs: dist/mailpress-installer.zip dist/mailpress.exe dist/print-files.ps1 - dist/config.example.json - dist/mailpress.ico dist/INSTALL.txt - name: release (on tag) @@ -60,8 +58,6 @@ jobs: dist/mailpress-installer.zip dist/mailpress.exe dist/print-files.ps1 - dist/config.example.json - dist/mailpress.ico dist/INSTALL.txt draft: false generate_release_notes: true diff --git a/README.md b/README.md index 06e2db4..d2c2c84 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,7 @@ wired Windows printer. Runs as a Scheduled Task on the office PC. 2. Unzip it on the office PC, e.g. into `C:\mailpress\`. You'll see: ``` mailpress.exe ← double-click this - print-files.ps1 - config.example.json - mailpress.ico + print-files.ps1 ← PowerShell print helper (must sit next to the exe) INSTALL.txt ← step-by-step install guide ``` 3. Double-click `mailpress.exe`. The setup wizard runs on first launch: @@ -138,7 +136,6 @@ lib/ wizard.mjs # first-run interactive setup test.mjs # post-install test menu (--test) print-files.ps1 # PowerShell helper: print one or more files -config.example.json # template — copy to config.local.json assets/ icon.svg # source icon (envelope on slant + speed lines) icon.ico # multi-size .ico embedded into mailpress.exe diff --git a/config.example.json b/config.example.json deleted file mode 100644 index 1f38a02..0000000 --- a/config.example.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "_comment": "Copy this to config.local.json and fill in. config.local.json is gitignored.", - - "googleClientId": "FILL_IN_from_gauth_.local-credentials.json", - "googleClientSecret": "FILL_IN_from_gauth_.local-credentials.json", - - "gmailAddress": "FILL_IN_office_account@gmail.com", - "gmailQuery": "in:inbox category:primary is:unread", - - "printerName": "FILL_IN_Windows_printer_name (run Get-Printer on the office PC)", - - "pollIntervalMs": 300000, - - "tokenPath": "./.local-token.json", - "spoolDir": "./spool", - "logPath": "./mailpress.log", - - "notifyEmail": "yjturetsky@gmail.com", - "notifyFromAddress": "FILL_IN_office_account@gmail.com", - - "maxAttachmentBytes": 26214400, - "perPrintSleepMs": 3000 -} diff --git a/lib/config.mjs b/lib/config.mjs index 6c78325..486ecef 100644 --- a/lib/config.mjs +++ b/lib/config.mjs @@ -49,12 +49,6 @@ export function configPath() { return join(installRoot(), "config.local.json"); } -export function examplePath() { - // The example ships beside the source files. When running from a SEA exe, - // it may not be on disk — callers should handle ENOENT. - return join(installRoot(), "config.example.json"); -} - export function resolveInRoot(p) { return resolve(installRoot(), p); } @@ -106,7 +100,3 @@ export function validateConfig(cfg) { return errors; } -export function isConfigured() { - const cfg = loadConfig(); - return cfg && validateConfig(cfg).length === 0; -} diff --git a/lib/oauth.mjs b/lib/oauth.mjs index c664a10..bfc0f9c 100644 --- a/lib/oauth.mjs +++ b/lib/oauth.mjs @@ -182,5 +182,3 @@ export async function runConsent({ clientId, clientSecret, gmailAddress, port = return outer; } - -export { SCOPES }; diff --git a/scripts/build.mjs b/scripts/build.mjs index 6e6d79d..2a98341 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -153,19 +153,12 @@ async function embedIcon() { } function copyAssets() { - const assets = ["print-files.ps1", "config.example.json"]; - for (const a of assets) { - const src = join(ROOT, a); - if (existsSync(src)) { - copyFileSync(src, join(DIST, a)); - } else { - console.warn(`asset missing, skipping: ${a}`); - } - } - // The icon is embedded in the exe; also drop a copy beside it for users - // who want a desktop shortcut with a matching icon. - const ico = join(ROOT, "assets", "icon.ico"); - if (existsSync(ico)) copyFileSync(ico, join(DIST, "mailpress.ico")); + // Only files mailpress.exe actually loads at runtime ship next to it. + // print-files.ps1 is invoked by lib/printer.mjs for each print job. + // Icon is already embedded in the exe; config is created by the wizard. + const src = join(ROOT, "print-files.ps1"); + if (existsSync(src)) copyFileSync(src, join(DIST, "print-files.ps1")); + else console.warn(`print-files.ps1 missing — printing will fail at runtime`); } // Drop a plaintext install guide into the bundle so anyone who unzips it @@ -174,7 +167,22 @@ function writeInstallTxt() { const content = `mailpress - Gmail-to-printer relay =================================== -INSTALL (Windows, ~5 minutes including the Google OAuth client step): +WHAT'S IN THIS FOLDER + + mailpress.exe double-click this to install + print-files.ps1 PowerShell print helper (must stay next to the exe) + INSTALL.txt this file + +After the wizard runs, you'll also see these auto-generated files +appear in the same folder: + + config.local.json your config (gitignored, contains client secret) + .local-token.json your OAuth refresh token (gitignored) + mailpress.log poll-loop activity + mailpress-setup.log every prompt + response from the wizard + + +INSTALL (Windows, ~5 minutes including the Google OAuth client step) 1. Copy this entire folder somewhere stable on the office PC. Recommended: C:\\mailpress\\ @@ -197,7 +205,7 @@ Google requires a human in a browser for that. The wizard prints the exact URLs and what to paste back. -USEFUL COMMANDS (run from a console in this folder): +USEFUL COMMANDS (run from a console in this folder) mailpress poll forever (or run wizard if not configured) mailpress --test switch printer, test print any file, change @@ -208,12 +216,6 @@ USEFUL COMMANDS (run from a console in this folder): mailpress --uninstall remove the scheduled task mailpress --help full command list - -LOGS - - mailpress.log poll-loop activity - mailpress-setup.log every prompt + response from the wizard - If anything goes wrong, run "mailpress --doctor" first - it identifies which subsystem (config, token, Gmail API, printer, scheduled task) broke and what to do about each. @@ -245,7 +247,7 @@ async function main() { writeInstallTxt(); smokeTest(); console.log(`\nDone. Artifacts in ${DIST}:`); - for (const f of [EXE_NAME, "print-files.ps1", "config.example.json", "mailpress.ico", "INSTALL.txt"]) { + for (const f of [EXE_NAME, "print-files.ps1", "INSTALL.txt"]) { if (existsSync(join(DIST, f))) console.log(` ${f}`); } }