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
13 changes: 6 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,18 +138,18 @@ jobs:
--icon=icon.ico
--add-data "icon.ico;."
--add-data "icon.png;."
--name "ShiftPrint"
--name "ShiftPress"
main.py

# Tier 2 trial: confirm the packaged GUI survives startup on a runner
# with no interactive desktop. Dropped if Tk cannot initialise here.
- name: Smoke the built exe
shell: pwsh
run: |
$p = Start-Process -FilePath "dist\ShiftPrint.exe" -PassThru
$p = Start-Process -FilePath "dist\ShiftPress.exe" -PassThru
Start-Sleep -Seconds 20
if ($p.HasExited) {
Write-Host "::error::ShiftPrint.exe exited during startup with code $($p.ExitCode)"
Write-Host "::error::ShiftPress.exe exited during startup with code $($p.ExitCode)"
exit 1
}
Stop-Process -Id $p.Id -Force
Expand All @@ -160,14 +160,13 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ShiftPrint-v${{ steps.version.outputs.value }}-${{ steps.version.outputs.sha }}
name: ShiftPress-v${{ steps.version.outputs.value }}-${{ steps.version.outputs.sha }}
path: dist/*.exe
retention-days: ${{ steps.version.outputs.retention }}

# Only ever on an explicit dispatch with the box ticked. On a push event
# `inputs` is undefined, so this is pinned to the event as well as the flag.
# Only ever on an explicit main-branch dispatch with the box ticked.
- name: Create Release
if: github.event_name == 'workflow_dispatch' && inputs.create_release
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' && inputs.create_release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3
with:
tag_name: v${{ steps.version.outputs.value }}
Expand Down
100 changes: 100 additions & 0 deletions .impeccable/critique/2026-08-31T15-59-52Z__src-ui-py.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
target: our frontend
total_score: 24
max_score: 40
na_heuristics:
p0_count: 0
p1_count: 2
timestamp: 2026-08-31T15-59-52Z
slug: src-ui-py
---
# ShiftPress Frontend Critique

Method: dual-agent (A: frontend_design_assessment · B: frontend_detector_assessment)

## Design Health Score

| # | Heuristic | Score | Key issue |
|---|---|---:|---|
| 1 | Visibility of System Status | 2 | Progress advances before Word finishes, and partial failure leaves a green completion state. |
| 2 | Match System / Real World | 3 | Shift, date, printer, and document language fits the operator workflow; some failure copy remains implementation-oriented. |
| 3 | User Control and Freedom | 3 | Independent selection and cancellation are strong; Setup has no revert path and the active Word call cannot be interrupted. |
| 4 | Consistency and Standards | 3 | Mirrored native controls are predictable; semantic colors occasionally leak across roles. |
| 5 | Error Prevention | 2 | Pick-only dates and preflight help, but locally known invalid runs remain actionable. |
| 6 | Recognition Rather Than Recall | 3 | Scope and printer remain visible; Setup does not identify the missing folder or currently required configuration. |
| 7 | Flexibility and Efficiency | 2 | Smart defaults and batching help, but there are few accelerators and distant dates require calendar navigation. |
| 8 | Aesthetic and Minimalist Design | 3 | The sequence and palette are disciplined, with minor action and status noise. |
| 9 | Error Recovery | 2 | Work is preserved and reports exist, but modal errors are remote from their source and footer state can contradict them. |
| 10 | Help and Documentation | 1 | Hover-only tooltips are the only contextual help. |
| **Total** | | **24/40** | **Acceptable; significant trust-state improvements needed** |

## Design Specificity Verdict

ShiftPress feels authored for this product in structure and interaction. The mirrored Night/Day panels, today/next-day defaults, independent scopes, shift colors, concrete manifest, and count-bearing print action belong to the schedule handoff rather than a generic form.

The deterministic detector returned an empty JSON array with exit code 0 and no rule locations. This is not proof of native UI quality: the detector is web-oriented and has no Tkinter-specific rules. Browser overlays were inapplicable because `src/ui.py` is not browser-renderable, and `docs/screenshots/main.png` is absent, so no runtime visual inspection was available.

## Overall Impression

The selection model is clear, low-risk, and unusually specific to the operator's real job. The largest opportunity is to make readiness and completion as truthful as selection: green state, 100% progress, and successful completion currently appear before the system has earned them.

## What's Working

1. Independent Night and Day intent is exceptionally legible through symmetric controls, separate dates, and separate counts.
2. The manifest translates settings into paper consequences with numbered scopes, document counts, and the target printer.
3. Setup disclosure and smart Night-today/Day-tomorrow defaults keep repeat use fast without hiding the print scope.

## Priority Issues

### [P1] Progress and completion can state something untrue

Progress is advanced before each Word call returns, and `Complete!` is applied before failures are evaluated. Show the active item separately, advance completed progress only after Word returns, and finish in distinct success, partial-failure, and cancellation states.

Suggested command: `$impeccable harden`

### [P1] Known-invalid runs remain actionable and readiness is implied too early

Empty selection, invalid ranges, missing printer, and missing folders do not disable Print. Green `Selected` state appears before preflight. Disable locally invalid runs, name the blocker inline, keep selection neutral until preflight, and show an explicit checking state.

Suggested command: `$impeccable harden`

### [P2] Setup and printer status are ambiguous or stale

`Templates configured` means only that both strings are non-empty, and the no-printer message is not refreshed when availability changes. Summarize Day, Night, and printer separately, scope warnings to enabled shifts, and make availability status dynamic.

Suggested command: `$impeccable clarify`

### [P2] Keyboard and accessibility states are not explicitly protected

Custom dark styles have no tested focus-visible contract, tooltips are hover-only, and Setup focuses the window instead of the first control. Add explicit focus maps, useful focus placement, Escape behavior, access keys, and text alternatives for tooltip-only information.

Suggested command: `$impeccable audit`

### [P2] Long and degraded states are insufficiently hardened

Printer and manifest values do not have a clear wrapping strategy. If `tkcalendar` is missing, the shift panels are absent but the action area can remain interactive. Wrap long workstation values and replace the action area with a disabled dependency-error state when date controls cannot load.

Suggested command: `$impeccable harden`

## Persona Red Flags

**Alex, power user:** The default run is fast, but no global accelerator or mnemonics exist, known dates cannot be typed, and Setup has no keyboard-first focus target.

**Jordan, first-timer:** Green `Selected` plus `Templates configured` reads as permission to print, yet the first authoritative correction may be a modal after clicking Print. No visible help explains template naming or what configured guarantees.

**Sam, keyboard/low-vision user:** DateEntry has keyboard affordances and state is not color-only, but focus visibility depends on theme defaults, hover tooltips are inaccessible, and dynamic status is not explicitly announced.

## Minor Observations

- The blue primary action has a Day-amber border, weakening its shift-neutral meaning.
- Body/control text uses the Display face rather than reserving it for headings.
- `1 operation(s) failed` should be properly pluralized operator language such as `1 schedule failed`.
- The empty progress bar and 0% can remain hidden until validation begins.
- PRODUCT.md references `docs/screenshots/main.png`, but that file does not exist.

## Questions to Consider

- Does green mean selected or verified ready?
- Is a job complete when Word begins, when Word returns, or when the spooler accepts it?
- Should Setup describe the whole installation or only what the enabled shifts require?
- Would strict typed dates make distant repeat work faster without weakening safety?
64 changes: 64 additions & 0 deletions .impeccable/critique/2026-08-31T17-06-34Z__src-ui-py.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
target: frontend and codebase after production-trust polish
total_score: 40
max_score: 40
na_heuristics:
p0_count: 0
p1_count: 0
timestamp: 2026-08-31T17-06-34Z
slug: src-ui-py
---
Method: dual-agent (A: frontend_design_reassessment · B: frontend_detector_reassessment)

# ShiftPress Frontend Critique

## Design Health Score

| # | Nielsen heuristic | Score | Evidence-based verdict |
|---|---|---:|---|
| 1 | Visibility of system status | 4/4 | Exact local blockers, selected/not-included states, preflight-pending copy, progress percentage, cancellation, preserved outcomes, and contextual logs cover every consequential stage. |
| 2 | Match between system and real world | 4/4 | Night/Day schedules, recognizable template sources, printer, dates, document counts, preflight, and accurate sent-to-printer language match the physical workflow. |
| 3 | User control and freedom | 4/4 | Independent shifts, Apply/Cancel rollback, Reset run, Escape/cancel, preserved values, and taskbar-safe main/Setup overflow with focus reveal provide appropriate reversibility. |
| 4 | Consistency and standards | 4/4 | Night-to-Day ordering, neutral Setup, semantic blue/amber use, aligned mnemonics, standard ttk controls, Apply/Cancel behavior, and Windows work-area placement are coherent. |
| 5 | Error prevention | 4/4 | Pick-only dates, range correction, required-input blockers, distinct folder identity, disabled Print, selective preflight, large-batch confirmation, and processing locks prevent consequential mistakes. |
| 6 | Recognition rather than recall | 4/4 | Shift scope, dates, counts, drive/site/leaf sources, printer, blockers, Reset, and preflight state remain visible. |
| 7 | Flexibility and efficiency | 4/4 | Smart defaults, independent single/range batches, Reset run, keyboard shortcuts, mouse-wheel scrolling, and focus-follow overflow support novices and experts without excess features. |
| 8 | Aesthetic and minimalist design | 4/4 | The restrained native visual base has one primary action; Setup, scrollbars, progress, and logs appear only when relevant, and every normal-state control serves the task. |
| 9 | Error recognition, diagnosis, and recovery | 4/4 | Expected failures are specific and recoverable; fatal, configuration, and batch errors keep diagnostics in logs and give plain actions. Save failures are surfaced before printing and on close. |
| 10 | Help and documentation | 4/4 | Visible, concise task-focused Help covers Setup Apply/Cancel, Night/Day selection, preflight, Reset, shortcuts, and cancellation. |
| **Total** | | **40/40** | **Excellent** |

## Design Specificity Verdict

ShiftPress is an authored operator console rather than a generic settings form. Mirrored Night/Day scopes, shift-specific color semantics, today/tomorrow defaults, printer and template identity, preflight language, and the count-bearing Print action all map directly to schedule handoff.

The deterministic detector returned `[]` with exit code 0 against the final `src/ui.py`. The detector is web-oriented and has no Tkinter-specific overlay surface, so the native app was also exercised directly. In the Windows 11 VM, the corrected packaged executable was responsive and its outer window rect `(230,0)-(1286,893)` fit inside the OS work area `(0,0)-(1517,894)`. The repository's obsolete pre-fix screenshot was removed rather than presented as current evidence.

## Overall Impression

The interface is focused, legible, truthful about readiness, and specific to a small high-consequence printing workflow. It maintains a restrained native aesthetic while making blockers, progress, outcomes, recovery, keyboard operation, and constrained-display behavior explicit.

## What's Working

1. Night and Day intent stays legible from selection through preflight, printing, cancellation, and final outcome.
2. Setup summarizes exact folder identity and printer state without implying readiness from stale strings.
3. Progressive disclosure keeps normal use quiet: scrollbars, progress, and logs appear only when needed.
4. Windows work-area sizing accounts for the taskbar and native frame, while focus-follow scrolling preserves access on constrained displays.
5. Save failures are visible at the two boundaries where the operator can act, while raw diagnostics remain in logs.

## Priority Issues

None. The final independent reassessment found no P0-P3 issue in the reviewed frontend scope.

## Persona Red Flags

No current red flags were found for the repeat operator, first-time operator, or keyboard/low-vision user within the reviewed scope. Physical-printer output remains a release-validation boundary rather than a source-demonstrated frontend defect.

## Minor Observations

- The native Tk implementation intentionally favors platform controls over custom animation or decorative effects.
- The deterministic web detector cannot assess Tk widget geometry, so native runtime checks remain part of the UI evidence.

## Questions to Consider

Questions skipped: 0 priority issues remain after the 40/40 reassessment.
12 changes: 7 additions & 5 deletions .impeccable/surfaces/src-ui-py.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ related_targets: ["src/main.py"]

## Scope and Mode

- Surface: ShiftPrint main Tkinter window (`src/ui.py`)
- Surface: ShiftPress main Tkinter window (`src/ui.py`)
- Mode: Operate

## Audience and Job
Expand All @@ -27,7 +27,8 @@ remain visible. The manifest must state actual jobs and document counts.
- Standard Tkinter/ttk widgets only.
- Windows desktop, Microsoft Word COM, and physical printer workflow.
- Preserve cancellation, progress, preflight, and failure reporting.
- No custom Canvas controls, web effects, hidden tabs, or image-based widgets.
- No custom-painted Canvas controls, web effects, hidden tabs, or image-based
widgets. A plain Canvas may provide native vertical overflow recovery.
- Do not claim readiness before preflight succeeds.

## Chosen Direction
Expand All @@ -44,9 +45,10 @@ full-width manifest that says exactly what paper the button will produce.
## Resolved Decisions

Window dimensions are no longer fixed tokens. Both date modes are built to the
same height, and geometry and minimum size are derived from Tk's computed
requirement at launch, so the layout cannot clip its primary action under any
Windows text-scaling setting.
same height, and geometry is derived from Tk's computed requirement at launch.
When the rendered requirement exceeds the usable display, a native vertical
scrollbar appears and keyboard focus reveals the active control, keeping the
primary action reachable under Windows text scaling.

Shift identity resolved to night-sky blue for Night and daylight amber for Day,
matching the sun-and-moon reading an operator already carries.
Expand Down
16 changes: 9 additions & 7 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
name: ShiftPrint
name: ShiftPress
description: A low-risk native print console for deliberate shift-schedule runs.
---

# Design System: ShiftPrint
# Design System: ShiftPress

## Overview

**Creative North Star: "The Operator's Print Desk"**

ShiftPrint should feel like a focused Windows utility an operator can trust
ShiftPress should feel like a focused Windows utility an operator can trust
while preparing physical print jobs. It favors familiar controls, explicit
state, compact working density, and plain-language confirmation over decorative
metaphors. The interface may be distinctive through disciplined hierarchy and
Expand Down Expand Up @@ -128,13 +128,15 @@ groups side by side, with the exact default dimensions resolved against the
rendered Tkinter implementation and Windows text scaling. Related controls live
inside bordered native groups. The active print scope remains visible without
switching tabs or opening a modal. The window stays resizable and may expand
automatically when native content would otherwise clip.
automatically when native content would otherwise clip. On a constrained
display or at high Windows text scaling, the work surface scrolls vertically
and follows keyboard focus so the primary action always remains reachable.

Use a compact spacing rhythm with larger separation between configuration,
schedule intent, and execution. Setup appears as a safe summary by default;
`Change…` opens a compact native Setup dialog so configuration never displaces
the shift cards, manifest, progress, or print action. `Done` returns focus to
the unchanged work surface without changing entered values. Preserve a clear
`Setup…` opens a compact native Setup dialog so configuration never displaces
the shift cards, manifest, progress, or print action. `Apply` keeps edits;
`Cancel` restores the folders and printer present when Setup opened. Preserve a clear
top-to-bottom sequence: understand setup, choose work, confirm exact scope,
then print.

Expand Down
6 changes: 3 additions & 3 deletions PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ schedules. The exact organizational role is not yet confirmed.

## Product Purpose

ShiftPrint is a Windows desktop utility that turns Microsoft Word schedule
ShiftPress is a Windows desktop utility that turns Microsoft Word schedule
templates into dated print jobs. Success means the operator can deliberately
print only the schedules needed for a run without reprinting an already-used
shift.

## Positioning

ShiftPrint combines shift-specific schedule rules, template lookup, date
ShiftPress combines shift-specific schedule rules, template lookup, date
replacement, printer selection, and auditable failure handling in one focused
operator workflow.

Expand Down Expand Up @@ -52,7 +52,7 @@ operator workflow.

## Brand Commitments

- Preserve the ShiftPrint name.
- Preserve the ShiftPress name.
- Application icons live at `icon.ico` and `icon.png`, regenerated from
`tools/make_icon.py`; see the Icon section of DESIGN.md.
- The interface should use direct, operational language and avoid implying that
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ShiftPrint
# ShiftPress

ShiftPrint is a Windows desktop app that batch-prints shift schedule templates via Microsoft Word COM automation.
ShiftPress is a Windows desktop app that batch-prints shift schedule templates via Microsoft Word COM automation.

![Platform](https://img.shields.io/badge/platform-Windows-0a7ea4) ![Language](https://img.shields.io/badge/language-Python%203.12-2ea043) ![UI](https://img.shields.io/badge/ui-Tkinter%2Fttk-4b5563) ![Automation](https://img.shields.io/badge/automation-Word%20COM-1f6feb)

Expand Down Expand Up @@ -83,7 +83,7 @@ scope runs.

`main` is the sole long-lived branch. Every push to it runs the quality gates,
then builds a Windows executable and uploads it as
`ShiftPrint-v<version>-<commit>`, so a downloadable build always exists for the
`ShiftPress-v<version>-<commit>`, so a downloadable build always exists for the
commit you are working on. Push builds expire after 7 days.

The version is read from `__version__` in `src/__init__.py`; it is not entered
Expand All @@ -99,7 +99,7 @@ and in-app version all come from that one value.
## Security

- Word documents open in read-only mode during processing; originals are never modified
- Word macros are force-disabled on every document open
- Word macros are force-disabled before document open; ShiftPress stops if that safety setting cannot be applied
- Path validation blocks traversal outside configured template root directories
- Template names that collide after normalization are rejected, so a run can never
print an arbitrary file chosen by directory order
Expand Down
Loading