Live #rawPrintPanel in Stage 2 — unmanaged lp spool path (docs/11/21):
Controls: printerSelect (lpstat -e, auto-refresh when the manifest lands), printerStatusBadge (idle/printing/stopped from lpstat -p), printerTraySelect + printerMediaTypeSelect from lpoptions -l capabilities, btnOrientPortrait/btnOrientLandscape, btnPrinterProperties (⚙︎ → bound NSPrintPanel), btnPrintAll + per-page btnPrintPage-N, in-panel printNotification (cancel → info, not error).
Not present on macOS: cupsOptionsGroup/chkPpdFallback — the PM-captured path is always used.
Preferences flow: cancel → info notice + no cache mutation; OK → captured options stored per-queue in capturedCupsOptions (session cache); a panel-side queue switch updates printerSelect when the returned CUPS id is in the list.
Spooling: sequential CupsService.printTarget per page, stop-on-first-error; wizardState.printerName recorded (#95).
Parser fix: lpoptions no longer truncates on a keyless =value token.
UI tests (Milestone3UITests): enumeration, cancel→info, captured options replayed in lp argv, per-page print, lp failure notice, printerName persistence — with mock lpstat/lpoptions/lp fixtures and the ICCERY_TEST_PRINT_PANEL stub.
⚠️Not run here: the dev machine's console was locked (IOConsoleLocked=true) — XCUIApplication.activate() cannot bring the app to front (verified identical failure on the M2 baseline). The suite must run unlocked or on CI. Core tests: 154 pass.
Live `#rawPrintPanel` in Stage 2 — unmanaged `lp` spool path (docs/11/21):
- **Controls**: `printerSelect` (lpstat -e, auto-refresh when the manifest lands), `printerStatusBadge` (idle/printing/stopped from `lpstat -p`), `printerTraySelect` + `printerMediaTypeSelect` from `lpoptions -l` capabilities, `btnOrientPortrait`/`btnOrientLandscape`, `btnPrinterProperties` (⚙︎ → bound `NSPrintPanel`), `btnPrintAll` + per-page `btnPrintPage-N`, in-panel `printNotification` (cancel → **info**, not error).
- **Not present** on macOS: `cupsOptionsGroup`/`chkPpdFallback` — the PM-captured path is always used.
- **Preferences flow**: cancel → info notice + no cache mutation; OK → captured options stored per-queue in `capturedCupsOptions` (session cache); a panel-side queue switch updates `printerSelect` when the returned CUPS id is in the list.
- **Spooling**: sequential `CupsService.printTarget` per page, stop-on-first-error; `wizardState.printerName` recorded (#95).
- **Parser fix**: `lpoptions` no longer truncates on a keyless `=value` token.
**UI tests** (`Milestone3UITests`): enumeration, cancel→info, captured options replayed in `lp` argv, per-page print, `lp` failure notice, `printerName` persistence — with mock `lpstat`/`lpoptions`/`lp` fixtures and the `ICCERY_TEST_PRINT_PANEL` stub.
⚠️ **Not run here**: the dev machine's console was locked (`IOConsoleLocked=true`) — `XCUIApplication.activate()` cannot bring the app to front (verified identical failure on the M2 baseline). The suite must run unlocked or on CI. Core tests: 154 pass.
Closes #17.
Generated with [Devin](https://devin.ai)
- rawPrintPanel: printerSelect (lpstat -e, auto-refresh on manifest),
printerStatusBadge (idle/printing/stopped), printerTraySelect +
printerMediaTypeSelect from lpoptions -l capabilities, portrait/
landscape toggle, btnPrinterProperties (bound NSPrintPanel), Print
All + per-page btnPrintPage-N, in-panel printNotification (cancel →
info, not error). No cupsOptionsGroup/chkPpdFallback — macOS always
uses the PM-captured path.
- TargetWorkflowViewModel: refreshPrinters, reloadSelectedCapabilities,
openPrinterPreferences (panel-side queue switch updates the select),
printAllPages / printPage (sequential, stop-on-first-error),
capturedCupsOptions per-queue session cache, wizard.printerName set
on spool (#95).
- CupsError.noPrinterSelected.
- Mock CUPS fixtures: lpstat (2 queues, one idle one disabled),
lpoptions (tray/media/EPIJ_CMat listings), lp (appends argv to
ICCERY_TEST_LP_ARGV). Milestone3UITests: enumeration, preferences
cancel→info, captured options replayed in argv, per-page print,
lp failure notice, printerName persistence.
- lpoptions parser: skip keyless '=value' tokens instead of truncating.
UI tests written but not executed here: the dev machine's console is
locked (IOConsoleLocked=true) so XCUIApplication.activate() cannot
bring the app to front — same failure on M2 baseline. Suite must be
run unlocked / on CI.
Generated with [Devin](https://devin.ai)
Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Ensure unstructured Task closures in TargetWorkflowViewModel and
Stage2View run on @MainActor after awaiting CupsService / spool.
Without this, updates in the failure path were
not reaching the UI in time, failing Milestone3UITests.
- lpoptions parser: a token no longer truncates the whole
parse.
UI test results: Milestone3UITests 6/6 pass; Core tests 154/154 pass;
universal arm64 x86_64 build passes.
gronod
merged commit ad6f8247d2 into milestone/m3-printing2026-09-09 07:07:13 +01:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Live
#rawPrintPanelin Stage 2 — unmanagedlpspool path (docs/11/21):printerSelect(lpstat -e, auto-refresh when the manifest lands),printerStatusBadge(idle/printing/stopped fromlpstat -p),printerTraySelect+printerMediaTypeSelectfromlpoptions -lcapabilities,btnOrientPortrait/btnOrientLandscape,btnPrinterProperties(⚙︎ → boundNSPrintPanel),btnPrintAll+ per-pagebtnPrintPage-N, in-panelprintNotification(cancel → info, not error).cupsOptionsGroup/chkPpdFallback— the PM-captured path is always used.capturedCupsOptions(session cache); a panel-side queue switch updatesprinterSelectwhen the returned CUPS id is in the list.CupsService.printTargetper page, stop-on-first-error;wizardState.printerNamerecorded (#95).lpoptionsno longer truncates on a keyless=valuetoken.UI tests (
Milestone3UITests): enumeration, cancel→info, captured options replayed inlpargv, per-page print,lpfailure notice,printerNamepersistence — with mocklpstat/lpoptions/lpfixtures and theICCERY_TEST_PRINT_PANELstub.⚠️ Not run here: the dev machine's console was locked (
IOConsoleLocked=true) —XCUIApplication.activate()cannot bring the app to front (verified identical failure on the M2 baseline). The suite must run unlocked or on CI. Core tests: 154 pass.Closes #17.
Generated with Devin