Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]

### Added
- **Machine-wide MSI for IT departments**: every release now also has `Rotula-X.Y.Z-win-x64.msi`, signed like the setup program. It installs to Program Files for every user with a Start menu entry and the `.rotula` association, upgrades older versions in place, and is made for silent deployment with Intune, Group Policy or Configuration Manager. The setup program can now also install for all users silently with `/ALLUSERS`. Silent install and uninstall commands, exit codes, Intune detection rules and Group Policy steps are in the new [docs/deployment.md](docs/deployment.md).
- **Settings your organization can manage**: administrators can fix the language and switch the update check on or off for everyone, suggest a default printer, keep add-ons in the user's own folder from loading, and switch printing or database access of the MCP server off, through Group Policy or Intune. Administrative templates (English and Spanish) are in `packaging/policies`. A setting fixed this way is greyed out in Rotula with "Managed by your organization".
- **Optional update check** (Help > Check for updates once a day): off unless you switch it on. Then Rotula asks GitHub once a day, with one anonymous request that carries nothing about you or your PC, whether a newer version exists, and shows a notice with a link to the release page. It never downloads or installs anything.
- **winget**: the manifests use schema 1.10, offer the MSI for `--scope machine` next to the per-user installer, and have a Spanish (es-MX) description. The submission steps are in docs/releasing.md.
- **Print station** for the warehouse floor: a locked, print-only screen started with `Rotula.exe --station <folder, station.json or label>` (without a path it uses `%ProgramData%\Rotula\station.json`) or from **File > Open print station**. Labels show as large tiles with thumbnails and a search box; scanning a label's code opens it. Its questions are large fields that take keyboard-wedge scanner input: Enter or Tab moves to the next one, the last scan can print at once, and the label's own rules (required, length, pattern) are checked before anything is sent. Printing goes through the same print path as the Print dialog with the printer status check, and the result is shown in large plain words (ready, held back with the reason, printed and verified, not confirmed); the questions then reset for the next item, keeping the answers the station is told to keep. A `station.json` sets the labels and their scan codes, the printer of each label or a default, copy limits, whether the label's data may be printed, and an exit PIN stored only as a salted PBKDF2 hash (made with **File > Create print station PIN** or `Rotula.exe --station-pin`); five wrong PINs lock the PIN box for 30 seconds. Every setting is checked and a mistake is explained with the setting and line. See [docs/print-station.md](docs/print-station.md).
- **Printer status before and after printing** (ZPL `~HS`). Before each job Rotula asks the printer for its status and does not send while it reports it is out of labels, its printhead is open, the ribbon is out, it is paused, too hot, in diagnostics mode or its buffer is full; the Print dialog says which and what to do. After the job it waits (up to 30 seconds) until the printer reports it finished, then says "printed and verified", names a fault that appeared after the job (the labels still count as possibly printed, so no serial number is reused), or says it could not confirm. A printer that cannot answer never blocks printing. On by default for network printers and off for Windows printers, switchable in the Print dialog; "Check printer status" shows the decoded answer at any time. The MCP server has a matching `get_printer_status` tool.
- **A gallery of eight showcase labels** in the README (GS1-128 pallet, parcel, food, wine, lab specimen, asset tag, shelf tags with data merge, print conditions). Their `.rotula` files and the CSV data are in `docs/showcase`, and the pictures are rendered with Rotula's own PNG export by a test that only runs when `ROTULA_RENDER_SHOWCASE=1` is set.
Expand Down
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ in [SECURITY.md](SECURITY.md), not a public issue.

These are product rules; changes that break them will not be merged.

- **Offline-first**: no network calls, no telemetry, no update checks, no analytics. Printing to the printer address the user
entered is the only network traffic.
- **Offline-first**: no telemetry, no analytics, and no network traffic unless the user asks for it: printing to the printer
address the user entered and the databases the user connects. The one exception is the **opt-in update check**: it sends
nothing unless the user (Help menu) or an administrator (policy) explicitly switches it on, and then it is at most one
anonymous `GET` of the public GitHub "latest release" API a day, with nothing about the user or the computer in it. It never
downloads or installs anything. Do not add other network calls, and do not add anything to that request.
- **Light theme only.**
- **Spanish and English** through `.resx` resources (`src/Rotula.App/Resources/Strings.en.resx` and `Strings.es.resx`). Every new
user-visible string needs both. Core returns message keys, not text.
Expand Down
20 changes: 14 additions & 6 deletions README.es.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ Siempre la versión más reciente: [github.com/P4Software/Rotula/releases/latest
|---|---|---|
| **Instalador** | `Rotula-<versión>-win-x64-setup.exe` | Instalación por usuario, acceso en el menú Inicio e icono de escritorio opcional. Firmado digitalmente |
| **Portátil** | `Rotula-<versión>-win-x64-portable.zip` | Descomprime en cualquier carpeta y haz doble clic en `Rotula.App.exe`. No instala nada. No necesita .NET |
| **MSI (para TI)** | `Rotula-<versión>-win-x64.msi` | Instalación para todo el equipo en Archivos de programa, para todos los usuarios, con Intune, directiva de grupo o Configuration Manager. Firmado. Consulta la [instalación en empresas](docs/deployment.md) (en inglés) |
| **winget** | `winget install P4Software.Rotula` | Próximamente. El manifiesto del paquete está preparado, pero aún no fue aceptado en el catálogo de winget |

Para instalar Rotula en toda una organización (instalación silenciosa, el MSI, Intune, configuración por directiva de grupo):
[docs/deployment.md](docs/deployment.md) (en inglés).

Cada versión incluye además un archivo `SHA256SUMS.txt`.

<details>
Expand Down Expand Up @@ -212,8 +216,9 @@ El software de etiquetas ha significado casi siempre una licencia de pago, una c
es un único programa de escritorio que hace el trabajo y no estorba.

- **Gratis y con licencia MIT.** Úsalo en casa, en la oficina, en un almacén o dentro de un producto. Sin puestos ni planes.
- **Sin conexión por diseño.** Sin analítica, sin búsqueda de actualizaciones, sin sincronización en la nube. El único tráfico
de red que Rotula puede generar es la etiqueta que envías a la dirección de impresora que escribiste.
- **Sin conexión por diseño.** Sin analítica, sin telemetría, sin sincronización en la nube. El único tráfico de red que
Rotula puede generar es la etiqueta que envías a la dirección de impresora que escribiste, las bases de datos que conectas
y, solo si la activas, una búsqueda de actualizaciones anónima al día.
- **ZPL honesto.** La misma etiqueta con los mismos datos siempre da ZPL idéntico byte a byte, en ASCII puro.
- **Errores que puedes resolver.** Un dígito verificador EAN-13 inválido o un carácter que no existe en Code 39 se reporta en
lenguaje sencillo, con lo que debes hacer a continuación.
Expand Down Expand Up @@ -452,9 +457,12 @@ puedes cambiarlo en cualquier momento desde **Ver > Idioma**, sin reiniciar. El

## Privacidad

Rotula funciona totalmente sin conexión. No tiene telemetría, ni analítica, ni búsqueda de actualizaciones, ni cuentas, y no
hace llamadas de red. El único tráfico de red que puede generar es la etiqueta que envías a la dirección de impresora de red
que indicaste. Tus preferencias (idioma, unidades, archivos recientes, última impresora) son un pequeño archivo JSON en
Rotula funciona totalmente sin conexión. No tiene telemetría, ni analítica, ni cuentas, y no hace llamadas de red por su
cuenta. El único tráfico de red que puede generar es la etiqueta que envías a la dirección de impresora de red que indicaste
y las bases de datos a las que te conectas. **Ayuda > Buscar actualizaciones una vez al día** está desactivado hasta que lo
activas: entonces Rotula pregunta a GitHub una vez al día cuál es la versión más reciente (una sola solicitud anónima, no se
envía nada sobre ti ni sobre tu PC) y muestra un enlace cuando hay una más nueva. Nunca descarga ni instala nada. Un
administrador puede activarla o desactivarla para todos ([instalación en empresas](docs/deployment.md), en inglés). Tus preferencias (idioma, unidades, archivos recientes, última impresora) son un pequeño archivo JSON en
`%AppData%\Rotula`. Si el programa falla, escribe un registro en `%AppData%\Rotula\rotula.log` en tu PC y no lo envía a ningún lado.

---
Expand Down Expand Up @@ -525,7 +533,7 @@ flowchart LR
| `src/Rotula.Mcp` | El servidor MCP (un ejecutable aparte) |
| `src/Rotula.App` | La aplicación WPF |
| `tests/` | Pruebas xUnit y los archivos ZPL de referencia |
| `packaging/` | Script del instalador y plantillas del manifiesto de winget |
| `packaging/` | Script del instalador, proyecto del MSI, plantillas de directiva de grupo y plantillas del manifiesto de winget |
| `docs/` | [Cobertura ZPL](docs/zpl-coverage.md), [catálogo de medios](docs/stock-catalog.md), [proveedores de datos](docs/data-providers.md), [servidor MCP](docs/mcp.md), [impresión](docs/printing.md), [publicación de versiones](docs/releasing.md), [decisiones de diseño](docs/decisions.md) (en inglés) |

---
Expand Down
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ Always the newest version: [github.com/P4Software/Rotula/releases/latest](https:
|---|---|---|
| **Installer** | `Rotula-<version>-win-x64-setup.exe` | Per-user install, Start menu entry, optional desktop icon. Code-signed |
| **Portable** | `Rotula-<version>-win-x64-portable.zip` | Unzip anywhere and double-click `Rotula.App.exe`. Nothing is installed. No .NET needed |
| **MSI (for IT)** | `Rotula-<version>-win-x64.msi` | Machine-wide install to Program Files for every user, for Intune, Group Policy or Configuration Manager. Code-signed. See [deployment](docs/deployment.md) |
| **winget** | `winget install P4Software.Rotula` | Coming soon. The package manifest is prepared but not yet accepted into the winget catalog |

Installing Rotula for a whole organization (silent install, the MSI, Intune, Group Policy settings): [docs/deployment.md](docs/deployment.md).

Every release also carries a `SHA256SUMS.txt` file.

<details>
Expand Down Expand Up @@ -209,8 +212,9 @@ Label software has long meant a paid license, an account, a subscription or a se
does the job and stays out of the way.

- **Free and MIT licensed.** Use it at home, at work, in a warehouse or inside a product. No seats, no tiers.
- **Offline by design.** No analytics, no update checks, no cloud sync. The only network traffic Rotula can produce is the
label you send to the printer address you typed.
- **Offline by design.** No analytics, no telemetry, no cloud sync. The only network traffic Rotula can produce is the
label you send to the printer address you typed, the databases you connect, and, only if you switch it on, one anonymous
daily update check.
- **Honest ZPL.** The same label and data always give byte-identical ZPL, in plain ASCII.
- **Errors you can act on.** An invalid EAN-13 check digit or a Code 39 character that does not exist is reported in plain
language, with what to do next.
Expand Down Expand Up @@ -441,8 +445,12 @@ switch at any time from **View > Language**, with no restart. The installer is a

## Privacy

Rotula works fully offline. It has no telemetry, no analytics, no update checks, no account and makes no network calls. The
only network traffic it can produce is the label you send to the network printer address you entered. Your settings
Rotula works fully offline. It has no telemetry, no analytics, no account and makes no network calls of its own. The
only network traffic it can produce is the label you send to the network printer address you entered and the databases you
connect to. **Help > Check for updates once a day** is off until you switch it on: then Rotula asks GitHub once a day which
version is the newest (one anonymous request, nothing about you or your PC is sent) and shows a link when there is a newer
one. It never downloads or installs anything. An administrator can switch the check on or off for everyone
([deployment](docs/deployment.md)). Your settings
(language, units, recent files, last printer) are a small JSON file in `%AppData%\Rotula`. If the program ever fails, it
writes a log to `%AppData%\Rotula\rotula.log` on your PC and sends it nowhere.

Expand Down Expand Up @@ -514,7 +522,7 @@ flowchart LR
| `src/Rotula.Mcp` | The MCP server (a separate executable) |
| `src/Rotula.App` | The WPF application |
| `tests/` | xUnit tests and the golden ZPL fixtures |
| `packaging/` | Installer script and winget manifest templates |
| `packaging/` | Installer script, MSI project, Group Policy templates and winget manifest templates |
| `docs/` | [ZPL coverage](docs/zpl-coverage.md), [stock catalogue](docs/stock-catalog.md), [database providers](docs/data-providers.md), [MCP server](docs/mcp.md), [printing](docs/printing.md), [releasing](docs/releasing.md), [design decisions](docs/decisions.md) |

---
Expand Down
3 changes: 2 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ changelog unless you prefer otherwise.
## What is in scope

Rotula is an offline desktop application. It makes no network calls except the printing you ask for (a TCP connection to the
printer address you enter). Reports of interest include:
printer address you enter), the databases you connect, and, only when you or your administrator switch it on, one anonymous
daily request to the GitHub "latest release" API (see [docs/deployment.md](docs/deployment.md#network-traffic-and-the-update-check)). Reports of interest include:

- Crashes, hangs or memory exhaustion when opening a crafted `.rotula`, ZPL, CSV or Excel file.
- Anything that causes Rotula to write outside the folders you chose, or to send data anywhere other than the printer you selected.
Expand Down
3 changes: 2 additions & 1 deletion THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ Specifications.
| Newtonsoft.Json (via the test SDK) | 13.0.3 | MIT |
| coverlet.collector | 6.0.4 | MIT |
| dotnet-reportgenerator-globaltool (CI only, installed on demand) | latest | Apache-2.0 |
| Inno Setup (CI only, builds the installer) | 6.x | Inno Setup License (free, redistribution of the tool is not part of Rotula) |
| Inno Setup (release build machine, builds the per-user installer) | 6.x | Inno Setup License (free, redistribution of the tool is not part of Rotula) |
| WiX Toolset SDK (`WixToolset.Sdk`, release build machine, builds the MSI; nothing of it is inside the MSI or the app) | 5.0.2 | MS-RL (Microsoft Reciprocal License); the tool is not redistributed |

## Data

Expand Down
Loading
Loading