# WinDevPilot

WinDevPilot is an MIT-licensed Windows 11 desktop app for keeping a developer
machine's software visible, understandable, and up to date. It brings WinGet,
Microsoft Store, language package managers, PowerShell resources, developer
toolchains, and carefully detected portable apps into one clear, account-aware
view.

Windows development machines rarely have one tidy package ecosystem. A global
npm tool follows a different update route from a machine-wide WinGet app and may
have a different owner; a Store package is not interchangeable with a similarly
named EXE; and a portable executable may have no package manager at all. WinDevPilot keeps
those distinctions instead of hiding them. It recommends ordinary updates,
explains uncertain or mismatched cases, and asks for elevation only when an
eligible machine-scoped action actually needs it.

Its goal is simple: offer the convenience of a unified update dashboard without
throwing away the evidence that makes an update safe. A scan never silently
becomes an install, conflicting evidence fails closed, and the underlying
package managers remain the authority for their own software.

Current showcase build: **1.3.28**.

This temporary showcase version opens **All packages** as a **large-icon gallery**,
using one combined color sweep (▲). It stays there when the startup scan finds
updates; click **Updates** to review them. Startup uses this presentation and an
empty search even when **Preserve settings** contains different display choices.

The application remains self-contained in `WinDevPilot.py`, including its GUI,
package providers and embedded vector renderer. This is its main README; separate
test scripts and development notes are not runtime dependencies.

## What WinDevPilot brings together

- **Updates you can review.** See actionable candidates from enabled providers,
  along with installed and available versions, scope, execution identity, and a
  plain-language safety status before anything changes.
- **A genuinely useful installed-app inventory.** Browse the combined **All
  packages** catalog, inspect package details and local paths, or save a compact
  system report suitable for your own records or careful troubleshooting.
  Click **All packages** again to toggle a vertically scrolling gallery with
  Package Details-sized icons and one name per tile. Click to select a tile;
  double-click to open Details, just as in the list.
  Right-click for the same package menu as the list. Arrow keys and Enter also
  work; Ctrl+Enter runs the focused package through the same checks as the list.
  Ctrl+mouse wheel toggles full-size and compact icons, once per wheel gesture.
  Compact images use a 5/8 (0.625) scale: 96→60 pixels at 100% DPI and 144→90
  at 150%. Compact PNGs preserve the exact nearest-neighbor pixels of the normal
  display rendition and are produced off-thread, without another extraction job.
  List and compact photos stay resident independently of the normal Details cache,
  including when leaving the gallery. Labels keep their normal font size, and the
  top visible package stays in view when toggling.
  Switching between list and gallery retains each view's scroll position for the
  current session; the two gallery sizes share the same approximate package position.
  Startup prepares both small tiers in adaptive, repaint-friendly batches, giving
  visible packages priority. Already decoded viewport icons attach together;
  decoding and cold preparation remain
  bounded, especially during dragging. Gallery entry can also use a soft 16-ms
  allowance including layout. A complete first frame is not guaranteed.
  Prepared generated icons can also finish during continuous dragging; their
  visible loading does not require an idle interval.
  Color sorting holds the displayed order during initial icon loading or cache
  regeneration. It applies the updated order after loading and scrolling settle,
  keeping the top visible package in view instead of rearranging each batch.
  A completed scan preserves already-loaded artwork for unchanged packages;
  changed identities, versions or source evidence still invalidate it.
  Search filters both presentations. **Updates** always uses the list; returning
  from Updates resets All packages to its list. Click **All packages** again to
  reopen the gallery.
  Compact spacing keeps the full-size icons closer together in both directions.
  Hold the left mouse button and drag vertically to scroll, then release for a
  gentle momentum glide, available even when Windows client animations are off.
  At either end, a pull meets increasing resistance and exposes a little blank
  space, then springs back on release. A glide reaching an end gets a small
  rebound too. Press again to catch the return and keep dragging. Stretch is
  limited to 72 DIPs or 20% of the viewport height, whichever is smaller.
  The gallery mouse wheel also glides and bounces at the ends. Each notch keeps
  the previous travel distance (three 24-DIP steps); repeated and partial wheel
  input accumulates toward that destination without adding extra fling distance.
  Scrollbar arrows move 24 DIPs per step. Holding or dragging
  never opens Details. Pause before releasing
  to stop without momentum, or use Escape, the wheel or another click to stop it.
  The **All packages list** also supports left-button dragging and release
  momentum. Its native table keeps moving in whole rows. Dragging or wheeling
  into either end adds a smooth, resisted pull of at most three-quarters of a row.
  The body returns over about 240 ms; wheel and coast arrival give a smaller pulse.
  Headings stay fixed and no blank package row is inserted. Reversing a drag
  releases the pull progressively; another interaction cancels it. Normal selection, modified clicks,
  double-click Details and column controls remain native. Updates keeps its
  existing mouse behavior.
- **Standard-user-first operation.** User-owned tools stay with the account that
  launched the app. Eligible machine work is grouped behind one UAC prompt, and
  Microsoft Store work never moves into a different administrator identity.
- **Fast feedback without invented certainty.** A saved inventory appears
  immediately on later launches, providers scan concurrently, and provisional
  rows are visibly marked until fresh evidence replaces them.
- **Verification after change.** Successful installer output is provisional.
  An automatic provider scan checks attempted providers first and reconciles
  those exact rows quickly. Untouched provider snapshots less than three minutes
  old can be retained; clicking **Scan** always bypasses reuse and checks every
  enabled provider again.
- **Useful caution rather than a wall of errors.** Holds, applicability checks,
  provider-specific diagnostics, restart memory, and bounded recovery guidance
  keep dubious retries out of the normal recommendation path.
- **Developer-machine extras.** Portable-app discovery, curated suggested
  installs, read-only Toolchain Health, icon inspection, structured logs, and
  privacy-conscious diagnostic bundles are built in.

You do not need every supported manager installed. Missing optional providers
remain unavailable, while the managers present on the machine continue to work.

## Project status

WinDevPilot 1.3.28 is an unreleased, source-run release candidate. It is already
a substantial daily-use application with deterministic safety tests,
non-installing CLI diagnostics, durable local state, and detailed failure
reporting. It is not
yet distributed as a signed installer or Microsoft Store app, and Windows 11 is
the only supported operating system.

That status is intentional rather than hidden: package-manager output and
vendor installers can be inconsistent, new provider versions can require parser
adjustments, and some updates genuinely need human review. WinDevPilot prefers
an unchecked row, a visible warning, or a narrowly scoped manual suggestion over
a confident-looking guess.

## How it works

```mermaid
flowchart LR
    U[User and Tk interface] -->|read-only scan| P[Provider adapters]
    P <--> S[Package CLIs, Store, registry, and portable roots]
    P --> N[Normalized inventory and completeness evidence]
    N --> G[Identity, scope, and recommendation policy]
    G --> U
    U -->|approved package action| R{Execution scope}
    R -->|launching user or Store account| P
    R -->|eligible machine action| E[Validated one-prompt elevated helper]
    E --> P
    P -->|attempted providers first| N
    U <--> L[Bounded logs and atomic local state]
```

Enabled providers scan concurrently and report independently, so one slow or
unavailable tool does not erase the others' evidence. Every result is normalized
before display or selection policy sees it. User-scoped and Microsoft Store work
stays in the launching account; the elevated helper accepts only a bounded,
validated plan for eligible machine-scoped actions. A successful command remains
provisional until the following inventory scan reconciles what is actually
offered.

## Quick start

Development checkout: `C:\Elements\WinDevPilot`. Vector editing and developer
showcases live separately in `C:\Elements\V64Vectorizer\VectorWorkshop`.
WinDevPilot remains standalone; moving its source does not move or clear the
per-account application data in `%LOCALAPPDATA%\WinDevPilot`.

- Windows 11 (the supported and tested platform)
- Python 3.12 or newer
- WinGet/App Installer recommended as the primary Windows provider
- `uv` for the one-time local `.venv` creation

The launcher creates `.venv` from an already-installed Python 3.12 or newer; it
does not download a Python runtime. The maintained development environment uses
CPython 3.14, while 3.12, 3.13, and 3.15 are explicit compatibility test lanes.

Keep the source files together, then double-click:

```text
Run-WinDevPilot.cmd
```

The maintained CMD launcher creates the environment through a visible `uv`
setup path when needed, then starts the GUI through `pythonw.exe`. The optional
`Run-WinDevPilot.vbs` compatibility launcher remains available on systems with
Windows Script Host, but normal launching and generated shortcuts do not depend
on VBScript. The generated `.venv` is local build state and is not part of the
source distribution.

Launch normally from the Windows account whose user-scoped tools you want to
manage. Do not switch to a different administrator account just to start the
app; when an eligible machine update needs elevation, WinDevPilot requests it at
the point of use. Let the initial provider scan complete, review the suggested
checkmarks, and choose **Update selected** only when you are ready.

To create Desktop and Start Menu shortcuts, run once:

```bat
Run-WinDevPilot.cmd shortcut
```

WinDevPilot has no third-party Python runtime dependencies. Icon resizing uses
the built-in, alpha-aware bilinear renderer; no optional image accelerator is needed.

Icon-color sorting groups reds through violet, then multicolor/rainbow artwork,
then black through white. Classification is cached with the icon pixels.

Generated fallback icons use the same standard-library VPL64/4 software core as
VectorWorkshop, including reusable/restylable parts, RGBA gradients and affine
geometry. Rendering remains cached and scheduled through the existing background
icon pipeline; this does not add a Workshop dependency or change package scanning.

If an earlier development build exists under the former application name, its
local settings, cached inventory, icons, and session history are moved into the
WinDevPilot application-data directory on first launch.

## Everyday workflow

### Scan once, see results arrive

The initial scan fills both main views:

- **Updates** shows actionable update candidates and their safety status.
- **All packages** shows the combined installed-package catalog.
- **Scan** refreshes both views in one pass.
- PowerShell 5 and PowerShell 7 each collect update and installed-resource data
  in one bounded shell process per normal scan. Their All packages phase reuses
  that exact snapshot instead of starting PowerShell a second time.
- **Scan portables** inventories portable apps under a folder you choose and
  retains those findings in All packages. It recognizes built-in signatures,
  valid PortableApps.com layouts, and high-confidence Windows executable
  identity evidence; ambiguous build artifacts stay hidden. Repeating a folder
  scan refreshes additions, removals, and local version metadata.

After the first complete scan, **All packages** can paint its last saved
non-portable inventory immediately on the next launch instead of waiting for
every package manager. Those rows are unmistakably provisional: both version
columns say `Checking…`, Status says `Previous inventory`, and package-changing
actions remain disabled. The existing summary strip reports `n/m providers
current` during refresh without reserving another permanent UI row. Each
provider replaces its previous rows as one complete batch. WinGet and Microsoft
Store are deliberately published together after their overlapping inventories
can be reconciled, preventing temporary duplicate or mismatched Store rows. A
stopped or incomplete scan retains still-useful previous rows with their
provisional labels rather than presenting them as current evidence.

While a provider or portable scan is running, **Stop scan** prevents queued
work from starting and lets already-running provider commands return safely.
Partial results are labelled stale rather than presented as a complete scan.
**Scan** also remains available during an update batch. Different package
managers scan in parallel. A manager that is actively installing immediately
retains its last trustworthy catalog instead of making the whole scan wait.
The refreshed tables preserve queued, in-progress, successful, and failed
package states. After a successful community WinGet update that does not require
a restart, a short exact-ID/source/scope installed-version query runs before the
next installer. When one unambiguous registration confirms the requested target,
both package views show the observed version and **Installed version verified**;
Details also identifies that early evidence. A concurrent scan retains it while
the remaining installers run. This is the default and needs no additional click
or UAC prompt. The elevated helper checks its own machine items between installers;
user items stay in the launching account. Failed or ambiguous reads leave versions
provisional, preserve the installer result, and never trigger an update retry.
Checks have a three-second query timeout and an eight-second total query budget
per execution phase (current-user or machine batch). A timeout skips the remaining
early queries in that phase. Other providers and restart-required results retain
their existing final-verification behavior.

The early query confirms the installed version, not the absence of a newer offer.
It does not write installation history or release holds. After the batch, one
automatic staged scan still starts attempted
providers first. Each attempted provider publishes its authoritative update
slice to reconcile the attempted rows as soon as ordinary update discovery
completes, then continues its complete installed-package inventory. Providers
that were untouched may retain a fully successful snapshot observed less than
three minutes earlier; expired, failed, incomplete, and attempted providers run
normally. WinGet and Microsoft Store always refresh or retain together because
their inventories overlap. The visible **Scan** button is the safety valve: an
explicit click ignores this grace period and checks every enabled provider. This
avoids redundant full scans, unnecessary CLI launches, and repeated table
repaints without presenting old or partial evidence as newly scanned.
Verification distinguishes the identical attempted candidate from a newly
available successor, treats interrupted provider reads as unverified, and
compares plain numeric versions semantically so cosmetic spelling changes do
not masquerade as new targets. A reboot-required result is remembered across
launches and excluded from recommendations until Windows has actually restarted;
the first successful provider scan after that boot either clears it or holds the
same still-offered target for review.
Restart memory uses Windows' successful-boot counter, so clock adjustments do
not count as restarts. Older records first establish a counter baseline and may
therefore need one additional restart. If Windows does not expose the counter,
WinDevPilot retains the pending state instead of claiming verification.

The main table includes the app icon, package name and ID, installed and
available versions, install/last-service date evidence when known, provider,
and status. Execution identity remains in Package Details and saved system reports
rather than a separate table column. An `≈` prefix marks an inferred date; hover it
to see the evidence and certainty. Header clicks sort the table. Quick search
matches package names first, then IDs, then providers. Updates, All packages,
and quick filtering remain available while scans or package operations continue.
Quick search receives the initial keyboard focus, so typing letters or numbers
immediately after startup begins filtering. Clicking a package row returns
keyboard focus to normal list navigation; `Ctrl+F` focuses search again.

Optional exact filters can narrow ordinary text searches:

- `provider:npm eslint` — npm packages matching “eslint”.
- `provider:portable` or `is:portable` — portable apps; plain `port` still works.
- `scope:machine is:admin` — machine-scoped rows whose package action requires admin.
- `is:selected` — checked packages, not merely highlighted rows.
- `is:held` — exact candidates with a current remembered attempt hold.

All conditions must match. Remaining words keep their normal phrase matching
and name-first ranking. Provider values use exact keys (`winget`, `npm`,
`portable`, `msstore`, and so on); convenient aliases include `store`, `dotnet`,
`.net`, `uv`, `powershell7`, and `choco`. `provider:steam` matches the proven Steam
installation channel, not its WinGet inventory adapter. Scope refers to the
WinDevPilot action scope shown in Details, not a word in a package description.
Incomplete filters and unknown values match nothing; unsupported field names
remain ordinary text. No quotes, OR expressions, or special syntax are needed
for normal searches. Filters never bypass holds, scope checks, or update confirmation.

Once urgent scan and interface work is quiet, a low-priority date sleuth fills
otherwise missing evidence without delaying results. For a portable app it uses
only a bounded, non-recursive look at the executable, nearby payload files, and
a containing folder whose name strongly matches the app or executable; generic
shared folders such as `Utilities` are never treated as app-date evidence. These
dates remain visibly approximate because portable software has no install ledger.
Accepted evidence is saved in the existing portable inventory against the
executable's size and modification time, so later views reuse it without
re-reading the surrounding folder and naturally discard it after the executable
changes.

Windows-package dates reuse the native enumeration already performed by the
Store scan, including date-only evidence for framework and non-Store packages
that WinGet lists. Exact current-account MSIX identities are matched before
publication and saved in the normal inventory cache. These date-only records
never add Store apps or update permissions. Each fresh scan reads current dates,
so even a same-version external reinstall can be observed without a long-lived
date cache or a second PowerShell launch. The idle query remains a fallback when
the main inventory cannot supply that evidence.

Approximate desktop dates inferred at idle are also saved in the existing inventory.
Later scans reuse them only for the same version, scope, source, location, and
registration evidence; fresh provider dates take precedence. Reusing a date does
not mark a provider freshly scanned or turn an estimate into a confirmed install.

Package Details also remembers successful installs and updates initiated by
WinDevPilot until its local app data is cleared. A suggested install therefore
gets a confident **Installed by WinDevPilot** timestamp, while an update is
truthfully labelled as the last WinDevPilot service action. The same details
view can show when an offered target version first appeared and the last
complete scan in which it was absent. That is a confident provider-visibility
window for this account—not a claim about the publisher's private release time.
The window rides in the already-atomic installed-inventory cache, and action
history is written only after refreshed inventory verifies an update or one
unambiguous installed row confirms a suggested install, adding no provider calls
or per-package cache churn. Display-source wording and row ordering do not break
the observation identity; provider, package ID, and scope remain authoritative.
Wall-clock evidence is retained at the best precision the source actually
provides. WinDevPilot observations, Windows PackageManager timestamps, registry
FILETIME service clues, and filesystem clues keep microseconds and time-zone
offsets. User-facing timestamps in the interface, Package Details, health panels,
human-readable logs, and reports are consistently rounded to a centisecond;
sorting and persisted evidence still use the full stored instant. Date-only
registry values remain date-only, while Details continues to identify the source's
actual recorded precision rather than treating display padding as stronger evidence.
The compact table cell remains date-oriented, but clicking **Installed / serviced**
sorts by the finest credible instant available: a verified action/native timestamp,
an inferred window's upper observation boundary, or a registry service-change time.
That preserves same-day installation order down through seconds and fractions.
The same cache now remembers every usable installed version. When a later complete,
fresh provider inventory sees an unambiguous package appear or its installed version
change, Details records the two-scan window in which that happened. A window wholly
within one local date yields an approximate service date; a window crossing midnight
shows both dates. This can date externally performed installs, updates, repairs, or
registration changes without another command or file write, but is not presented as
proof of the application's original installation date. Reused three-minute snapshots,
unknown versions, duplicate identities, and incomplete providers never advance it.
The table's **Installed / serviced** date, date sorting, tooltip, Details, and
system report all use that verified history when Windows/provider evidence is
missing, approximate, or no newer. A newer explicit Windows/provider date takes
precedence. History must match the exact provider, package ID, scope, and source;
an update is labelled **Updated by WinDevPilot**, never as the original install.
The original provider evidence remains available in Details. Existing saved
history works immediately on restart, without another install or special scan.
If a complete, freshly scanned provider inventory no longer lists a remembered
package, its earlier actions remain in Details as history, but no longer date
an installation that later returns. A new verified WinDevPilot action supplies
fresh date evidence. Failed, partial, and reused inventories never establish
absence. An external uninstall/reinstall entirely between scans cannot be detected.
“Installed-app registration last changed” refers to Windows' installed-app
registry entry—not an uninstall event.
For exact Steam uninstall registrations (`ARP\...\Steam App <id>`), Provider
means the proven installation channel and therefore reads **Steam**, even though
WinGet supplied the read-only installed-inventory row. Package details retain
that discovery provenance explicitly. Known products that have both a desktop
app and a command-line tool, including Claude and Codex, receive clear
`(Desktop app)` or `(CLI)` display labels while their stable package IDs remain
unchanged.

### Interface and reports

The interface follows Windows light/dark mode while running, uses per-monitor
DPI scaling, and keeps its Windows 11 title bars and square-corner treatment
consistent across app-owned windows. Drag the gradient divider between the
package table and log to resize either area. Right-click the log to copy a
selection, copy everything, or clear only the visible output; clearing it does
not delete the durable session logs.
Secondary windows are assembled while hidden, with their theme background and
title-bar colors ready before showing and taking focus. Icon Showcase retains
its deliberately chosen inspection background independently of Windows' theme.
The header, accent, and divider use reusable raster gradients. During a Windows
border resize, the interior temporarily retains its dimensions and fits the new
size when sizing ends; expanding can expose a theme-colored margin, and shrinking
can briefly clip controls. Ordinary window moves do not engage this hold.
Cancellation, theme changes, and DPI transitions release it safely. Resizing
does not rebuild package rows or rescale their cached icons unless DPI changes.
During either a native move or resize, optional icon decoding, cached-icon
painting, theme checks, and intermediate progress painting briefly yield to the
window gesture. Provider results and final scan completion continue to be
consumed and reconciled immediately; releasing the title bar is never required
for a scan to finish or report success.
Activity messages are written to the durable session log as they occur, then
messages from the same GUI event drain are painted together to avoid repeated
Text-widget state, trim, and scroll work. This does not defer provider state or
the final completion result to a later event cycle.
The event drain retains ownership across nested Tk callbacks and schedules its
next poll even if notification or log painting fails. Session logging admits at
most 16,384 queued ordinary records; overflow is counted and reported in both log
files. Flush/close requests retain FIFO ordering without waiting for queue space.
This bounds record count, not payload bytes, and overflow can omit diagnostics.
For comparison or a preference for continuously reflowing controls, launch with
the environment variable `WINDEVPILOT_RESIZE_HOLD=0`; raster gradients remain active.

List scrolling avoids repeated icon-priority work when no icons are queued and
defers hover highlights and tooltips until the gesture settles. Cached artwork
remains visible. Small Windows mouse-wheel deltas accumulate into whole rows
instead of being rounded independently; normal notch speed is preserved for
the recognized Tk 8.6/9.0 bindings. Modified-wheel, horizontal, and Tk's separate
touchpad bindings remain unchanged. This is row-based scrolling, not a new
pixel-scroll animation.

Local artwork discovery reuses directory-enumeration metadata to avoid repeated
file checks. Nearby-artwork searches stop enumerating at their existing entry
budget; selection priorities and image quality remain unchanged.
Portable scans also index Windows installation registrations once per scan,
avoiding repeated registration searches for each executable while preserving
exact-file and specific app-folder exclusions. A registration pointing at a
whole drive, profile, or shared tools folder cannot exclude unrelated apps.

The single-row toolbar keeps Scan, both package views, Scan portables, and
Update selected immediately available. Its sprocket menu holds the less-common
**Retry failed updates**, selection-helper, **Test once**, system-report, ignore/hold,
graphics-cache, and provider controls. **Clean icon and graphics cache…** asks
for confirmation, with Cancel selected by default, before clearing generated
artwork. Icons are recreated as needed. Installation-date metadata, package and
portable inventories, installation/update history, settings, logs, and original
application artwork are preserved. This action is unavailable while a scan,
package operation, or another cleanup is active. Ctrl+Scan no longer resets icon
quality data, and the header context menu no longer contains cache-clearing
actions. **Package details...** remains where it is most useful:
open it by double-clicking a row or using that row's context menu. **Save system
report…** opens a standard Save As dialog and writes a readable UTF-8 inventory
of the complete All packages catalog. Package blocks use compact `#n` headings
and include installed folders, service dates, technology, and size only when
known. Folder paths have redundant trailing separators removed and are quoted
when they contain whitespace. A compact header records Windows build and
architecture. Suggested installs and Toolchain Health remain a separate
right-aligned group.
The sprocket menu's **Preserve settings** checkbox is off by default. In the normal
startup mode, it restores the last package view, list/gallery presentation, icon
size, exact sort mode and search text. **The temporary showcase startup overrides
those display choices**, opening the large gallery with combined color sorting
and an empty search. Turning preservation off forgets the saved display choices.
Provider choices and window geometry continue independently; package selections
and running operations are never restored.
Each directly opened WinDevPilot secondary window receives normal focus when
it appears, so **Escape** works immediately. If focus is in an editable text
field, the first Escape leaves that field without discarding its contents and
the next Escape closes the window; native menus and file dialogs retain their
normal one-level Escape behavior.
The report omits unchanged Available values and Status for ordinary
installed-only rows. When an installed row has one exact identity match in the
current Updates view, Status reads `Update available — <version>`; ambiguous or
provisional evidence is never promoted.

### Updating and package actions

For updates:

1. Review the automatically recommended checkmarks.
2. Select or clear packages as needed.
3. Choose **Update selected**.
4. Follow progress in the activity strip and log pane.

The update bar shows a small solid-green activity marker as soon as Update starts
checking the selection, with a lighter moving/fading block during checks and the
first attempt. A fast check/refusal keeps a brief 450 ms acknowledgment visible;
this only controls the cue, never delays a confirmation, result, or installer.
The summary says whether checks or an installer are running. It is an activity cue,
not an invented download percentage. The main bar advances on completed package
attempts (including failed ones), not merely queued administrator jobs. Reduced
motion keeps the cue static, and decorative animation yields during window moves
without delaying result or completion messages.

A held-only selection offers **Review selected** in amber instead of an unexplained
disabled Update button. A known hold does not trigger a redundant manifest check.
If nothing can proceed, **No update started** appears in the summary, a temporary
attention banner, and the log. Double-click for Details; after addressing the
cause, keep the package checked and use **sprocket > Test once** for a deliberate,
confirmed retry. Normal Update never silently releases a hold.

After a failed command explicitly identifies a local file with an access/lock
error, WinDevPilot can ask Windows which processes are using that exact file.
The log names the file user and, when available, its launch chain—for example,
`uv.exe` launched through an IDE. Package Details retains that last-attempt
evidence; it is not a claim that those processes are still running. This is a
best-effort diagnostic with a one-second caller wait limit, not a background
process monitor. Scans and successful updates do not run it. Unknown output,
unavailable evidence, or an empty result leave the original failure guidance
intact. WinDevPilot never closes another app, changes permissions, or retries
automatically; file use is a likely blocker, not proof that permissions are correct.

**Select recommended** deliberately excludes pip packages. Shared Python user
sites can have dependency constraints that make bulk updating unsafe.

Right-click a package for context-sensitive actions. Depending on the row and
provider, this can include running a locally proven activation route from either
package view, updating that one package, opening or copying details, ignoring
it, or uninstalling it through an exact provider command. **Run** starts a verified
route in one action. Windows packaged apps use their visible manifest application
IDs, retained with the normal inventory; hidden helpers are not offered. Windows
account registration also supports non-Store MSIX apps through exact package IDs or an
explicit publisher-qualified family mapping (currently Claude Desktop). This
does not change which provider manages updates or substitute a similarly named CLI.
Start Menu `.lnk`/`.url` routes preserve the application's saved arguments and working directory.
Equivalent shortcuts collapse into one choice; distinct launchers appear in a
**Run** submenu. Portable apps and explicit registered executables remain supported.
A bounded, nonrecursive fallback checks verified installation folders for matching
PE executable identities; it does not pick an arbitrary EXE or search the drive.

Type to search immediately after startup, then **Ctrl+Enter** to run a single
search result, or select a row and press **Ctrl+Enter**. Ordinary Enter and
double-click still open Package Details. Verified routes also work while a
read-only scan is running, including preliminary cached rows; package-changing
operations keep Run disabled. Direct console executables open a visible terminal
that remains available after the command exits. WinDevPilot does not request
elevation for Run, although an application's own manifest may request it.
**Open containing folder** follows a bounded, cycle-safe local `.lnk` chain and
reveals the real executable or recognized hosted script when one exists, with a
proven executable or install-location fallback. **Open shortcut folder** appears
directly below it for saved `.lnk`/`.url` routes. **Run** still uses the original
shortcut unchanged, preserving its arguments, working directory, and launcher behavior.
Uninstall is intentionally conservative, always confirms the exact target, and
rescans afterward.

### Portable apps without pretending they are managed packages

Portable scanning recognizes CPU-Z, Notepad++, Rufus, and Chathy by built-in
signatures, validates PortableApps.com metadata, and admits other executables
only when independent local evidence makes portable identity highly likely.
Source and dependency folders are pruned, non-executable files do not consume
the candidate budget, cloud placeholders/reparse points are skipped, and
lower-confidence findings remain hidden. Strong app-local markers can reinforce
otherwise sound PE identity evidence; generic JSON/XML files cannot. The app
records whether each executable folder is on `PATH` and searches nearby files
for an icon. Windows and Program Files trees are rejected when selected directly
and pruned from broader drive scans, using their resolved system paths rather
than ambiguous folder-name guesses. A whole-drive scan applies stricter rules:
other account profiles, AppData application/cache trees, ProgramData components,
vendor staging areas, managed runtimes, and driver payloads are excluded, and
generic executables require affirmative portable evidence. On that broad scan,
a product-name/filename resemblance is weak unless a stable embedded original
filename or another independent portability signal corroborates it. A deliberately
selected bounded folder remains more permissive without treating the absence of
an uninstall entry as proof by itself. During a long scan, use **Stop scan** or
click the activity strip and choose **Stop portable scan**; the previous saved
inventory remains intact.

In the background, explicit or uniquely matched WinGet catalog entries can
supply a current version, homepage, and manifest download URL. If WinGet has no
safe match, a bounded fallback can inspect identity-matched, app-owned nearby
release/readme files and a declared official project page or GitHub release
feed for a version clue. Release wording must bind directly to the reported
version, so benchmark timings and unrelated dotted numbers are not treated as
releases. The fetcher accepts only corroborated hosts/repository identities and
refuses
cross-origin redirects; arbitrary links planted in a scanned README are not
contacted. Each app start also rechecks the local versions of known portable
executables after the main provider scan and before lower-priority large-icon
work. The source of an accepted clue remains visible. A confidently newer
release may appear as a selectable advisory in **Updates**, but WinDevPilot
will refuse to install it through the provider: replacing the portable files
manually preserves the layout the user deliberately chose.

Portable uninstall is offered only when WinDevPilot can prove either one
recognized standalone executable in a shared folder or one unambiguous,
app-owned folder. The confirmation names the exact deletion target, and the
filesystem is revalidated immediately before deletion. Ambiguous or shared
folders remain non-removable.

When every highlighted row is portable, the right-click menu also offers
**Clear selected portables from list**. This forgets only those saved inventory
entries; it never changes their files or folders. Scan the folder again to
restore them to the list.

## Package details and icons

Double-click any package row, or choose **Package details...** from its right-click
menu, to inspect:

- installed scope and owning account class;
- installer technology and location;
- installed size and install/service date evidence, including its source and certainty;
- exact package identity and product codes;
- WinGet manifest/preflight evidence;
- update guidance and local failed-attempt history;
- the best locally discovered icon and its processing details.

Windows Installer defines its `InstallDate` metadata as the last time a product
was installed or serviced, so it can change after an update or repair. Windows
package metadata similarly reports when an MSIX/AppX package was installed or
last updated. Uninstall-key activity and corroborated install-folder creation
times can fill some otherwise missing dates, but they are explicitly shown as
approximate and never described as the original install date. A single unrelated
file timestamp is not enough; uncertain dates remain blank. Folder estimates
require an inventory-supplied installed location and a payload inside that folder.
Artwork lookup results, shared branding, and similarly named CLI executables are
not installation evidence and cannot supply a missing installed location. The fallback
package-date query and bounded folder check run only after scans, updates,
portable checks, and icon preparation are all idle; normally Windows-package
dates are already present from the main native inventory.

Double-click the large package icon to open **Icon lineup**, which shows the
local representations WinDevPilot can retrieve from executables, icon files,
Start Menu shortcuts, packaged-app assets, and other Windows sources. Icons can
be saved from their context menus. Double-click a lineup image for a larger
Showcase view. Showcase uses Tk's integer nearest-neighbor scaling to reveal the
original pixels, colors, and alpha, without smoothing or color correction. It
chooses 3×, 2×, or 1× to fit the monitor; oversized sources use integer pixel
subsampling. Every backdrop uses a single native render of the supplied PNG,
without a loading indicator, rendering subprocess or later image replacement.
Showcase adds no extra contrast outline; any outline already present in the
supplied artwork remains. Before presentation, a bounded native pixel check
ignores fully transparent pixels and changes white-on-white or black-on-black
artwork to a medium-gray backdrop. It normally stops after the first contrasting
pixel and checks at most 256 samples. If sparse artwork falls between all samples,
the backdrop becomes checkerboard. No second render or helper process is involved.
Double-click an Icon Lineup image for a white Showcase backdrop; hold **Shift**
for black, or **Ctrl** for a checkerboard transparency check. Ctrl takes precedence
when both modifiers are held. These choices affect only Showcase, not the app theme
or normal list-icon rendering.
Discovery and image preparation happen in background workers;
warm results are cached locally for responsive browsing.
Showcase needs no additional preparation after the Lineup supplies its PNG.
Details rendering evidence is collected by the existing icon workers and reused
from a bounded memory cache keyed by package identity/version, source, size and
artwork revision. Missing evidence is refined asynchronously; the icon can appear
first. The decorative cursor does not stat a file; actual Save/Open actions retain
their validation. This keeps the warm icon-and-evidence path in memory, without
claiming that the entire Details window performs no filesystem work.
Rescans validate cached source-file timestamps and sizes in the background;
changed sources are refreshed, while unchanged artwork stays ready.
The startup catalog is saved as soon as list-icon preparation or warm-cache
recovery finishes; it no longer waits for large Details icons. Nearby save
requests are combined and written in the background. Closing during later
large-icon preparation therefore preserves already-checkpointed list artwork.

Validated PNGs also have immutable packed cache generations, read completely by a
worker before Tk sees their bytes. Missing or damaged pack entries fall back to
individual PNG files. The newest two generations per size/theme are retained at
startup. The display-v15 revision adds compact renditions and requires a one-time
refresh of derived artwork. List and compact photos are pinned for the current
inventory/DPI; normal Details photos use a 48-MiB estimated-storage LRU. Pinning
trades additional predictable RAM for stable compact scrolling; it is not a cap
on total process memory.

Ordinary list and Details artwork is resized from the supplied source pixels, without guessing whether
it was previously enlarged or reconstructing an inferred smaller original.
Resizing uses bilinear interpolation for both enlargement and shrinking, with
transparency cleanup and adaptive contrast outlines. Edge smoothing and outlines
skip distant transparent margins without changing the resulting pixels.
Switching from older artwork rendering requires a one-time background refresh
of derived icons; raw artwork and installation-date history are preserved.

Missing artwork now uses a small generated illustration instead of a minus:
Rust gears, code/editor marks, language/tool symbols, or a white, dark-outlined
wrench when the app is unknown. Real local artwork normally takes priority;
the .NET Native Runtime/Framework families deliberately use a crisp blue-purple
infinity ribbon in the list and Details instead of their tiny registered logos.
Microsoft Engagement Framework similarly gets a clean cyan left arrow, matched
by its exact package name across architecture/version variants. LLVM's fallback
is a simplified blue-and-white wyvern based on its [official visual identity](https://llvm.org/Logo.html).
This display-only exception retains the original artwork for inspection.
The Codex CLI fallback follows the scalloped cloud and terminal-prompt motif
shown in [OpenAI's Codex artwork](https://openai.com/academy/codex-for-work/),
with a fine contrast edge for light backgrounds. Cargo-binstall's white arrow
has one thin near-black outline around the combined shaft and arrowhead.
These are original simplified fallback illustrations, not official logos or
evidence of how an app was installed. They render directly at the requested list
or Details size with true transparency, with no downloads. Their PNGs share the
normal graphics-cache folder and atomic writer, keyed by drawing content and size
rather than by package. Subsequent sessions reuse the bitmaps; edits to a drawing
automatically select a new cache key. Background workers persist the files, not
the GUI paint path. Clean graphics cache includes these files and preserves
installation-date history.

Icon Lineup also includes clearly labeled generated bitmaps at list, Details,
and 512-pixel sizes, using the same save/showcase controls as found artwork.
Original artwork remains available alongside them. A generated-only lineup
does not need an extraction subprocess.
The generic wrench is only a fallback: it is omitted when usable artwork is
available, and obsolete per-app wrench references are dropped when artwork arrives.
Generated PNG bytes are shared by reference across in-memory galleries, not copied
into every app's packed bundle. Wrench files remain one per drawing version and
needed resolution in the shared graphics cache; no per-app files or shortcuts are made.

The narrow **Art** heading uses the same font as the other column headings.
Hover over it for a tooltip explaining the one- and two-triangle sort modes.
Click it once for a combined color sort (▲),
regardless of artwork origin. Click again for two color-sorted groups (△△):
generated illustrations first, then retrieved artwork. Further clicks alternate;
returning from another sort column starts with the combined mode. Sorting another
column restores the **Art** label. Colors run
from red through violet, then multicolor/rainbow artwork, followed by mostly
neutral icons from black to white. Balanced multicolor artwork can qualify with
a slightly smaller third color family; predominantly single-color icons keep
the stricter threshold. If one hue contributes at least 90% of measured color
strength, its own hue centers the result; tiny accents cannot shift the color
window toward their edge. Mixed gradients retain the existing neighborhood rule.
Transparent padding is ignored; votes weigh saturation and brightness so dark
tints stay neutral and clear colored marks count more. Missing color keys are computed from existing
bitmaps in the existing background worker and saved by bitmap content across launches;
unchanged artwork is not reclassified unless the color-rule revision changes.
The current revision is `appicon-colors-v7.json`; it does not invalidate artwork.
Cleaning the graphics cache removes these color statistics too. The displayed
package order stays stable while artwork is regenerated; the new color order is
applied once loading and scrolling settle. Sorting itself never starts icon
extraction or a package scan. Another column heading resumes ordinary sorting.

For generated vector artwork, Package Details lists the embedded renderer as
**VPL64 software16 v6 (language 4.3)** under Icon artwork, followed by the
displayed drawing script's character count excluding whitespace and source comments. Retrieved package
images do not receive this label. VPL64 is the new name for V64; internal
identifiers and existing cache keys remain compatible.

The inline **VPL64/4.3** format normally uses one character per coordinate on a 64-unit canvas.
An optional `^` before a geometry operator uses paired digits for 1/64-unit
precision in that word only. Existing compact drawings and their pixels stay unchanged.
A word is `[paint][/axis][width][.][!outline]geometry coordinates` (without spaces).
Geometry includes polygon/polyline (`P`), cubic/quadratic Bézier chains (`B`/`Q`),
circle/ellipse (`C`/`E`), gear (`G`), and rounded box (`R`: x, y, width, height,
corner radius). The [VPL64 reference](../V64Vectorizer/VectorWorkshop/V64_SPEC.md) covers fine widths,
gradient axes and the complete bounded grammar.
A width makes a stroke; `.` rounds its ends; `!` adds a dark outline to a fill
(`!k` selects outline color `k`). `~q`
specifies a quarter-unit width using one coordinate digit. Commas repeat the
same paint and geometry with another coordinate group. Omitted paint reuses the
previous color and gradient axis, but not its stroke mode. A new paint resets
the axis to the canvas diagonal. `bcg/0W_W` specifies a horizontal blue/cyan/green
gradient; end colors clamp rather than repeat. `;op` adds an even-odd contour
to the current fill, revealing any layers beneath its hole. `0` explicitly erases
all underlying artwork with antialiased edges; the wrench still needs this distinction.
Filled Bézier ribbons provide tapered highlights without a variable-width stroke
engine. For example, `rGWWSNG;CWWH` is a 16-tooth gear with an antialiased center hole.

`[A words ]` defines **and draws** a local part. `@A` repeats it; `@A~` mirrors
it across the canvas center. `@A:tx,ty,scale,degrees[,mirror]` applies uniform
scale, optional reflection (`-1`, otherwise `1`), and rotation about the origin,
then translation. Paint and gradient endpoints transform with the geometry;
part-local paint does not change the enclosing paint. The dragon defines each
wing/arm once and mirrors it. Definitions cannot nest, but an assembly can reference
earlier parts; forward references and recursion are rejected. Program length,
expanded shapes, transforms and output sizes are bounded.

Generated artwork uses a standard-library **software-only renderer**, with flat
stroke ends by default, optional round ends and round joins. V4's active-edge
sweep produces constant-coverage runs; opaque spans are copied in bulk rather
than painted pixel by pixel. A 16-bit premultiplied canvas preserves translucent
layer accumulation, with bounded, shared gradient ramps and fast output packing.
Ramp interpolation keeps its 16-bit precision; thin curved strokes are not snapped
to a pixel grid. The current V6 opacity policy uses a one-pixel footprint with
proportionally lighter ink for subpixel strokes; wider strokes keep their true width.
Pixel-identical implementation optimizations preserve existing bitmap cache keys,
installation history and retrieved app artwork.
It handles partial alpha, even-odd fills, gradients and transparent cutouts;
the test suite compares it against the former floating-point reference.
The retired native renderer and reinstatement guidance are preserved in the
project notes, not in runtime code. Windows extraction of existing app artwork
is separate and unchanged. Concurrent
requests share identical renders, and background warming prepares list sizes
before larger sizes. The 512-pixel showcase variants are prepared on Lineup
demand and through its background prefetch, not during ordinary startup.
Bounded memory and persistent bitmap caches share each design/size across packages.
Optional background cache warming waits for scans/updates to finish and follows
existing-icon restoration; explicitly requested Lineup artwork does not wait.
Small first-use UI icons remain immediately available, including the wrench.

ICO files are size-bounded, and frame selection copies only the chosen PNG
payload rather than duplicating image data for every directory entry.

Raw icon artwork is keyed by its source file version and extraction policy, not
by the package row that happened to discover it. Packages sharing one executable
or image therefore share one extraction and one raw cache entry; direct PNG art
also backs every display size. The current source-versioned cache is validated
directly; obsolete formats are pruned conservatively, and a temporary file is
left alone until it has been abandoned for at least an hour. Provider result
publications arriving close together are coalesced into one table rebuild while
still appearing incrementally, reducing repeated sort, filter, and icon work.

## Selection, ignores, and holds

- Right-click an eligible update and choose **Ignore this update** to hide it
  until restored through **Manage ignores**.
- **Holds** are temporary safety pauses learned from failed or risky exact
  update attempts, including a provider-reported success that a fresh provider
  verification scan contradicts by offering the identical candidate again.
  They prevent the same candidate from being silently recommended again. Holds
  produced by an older WinGet command strategy stop suppressing candidates when
  that strategy changes.
- Repeated WinGet “not applicable” results also inform later offers for the
  same unchanged installed instance. A changed installed version, scope,
  technology, or location naturally resets that caution.
- **Test once** deliberately bypasses a hold or cautious prediction for one
  diagnostic attempt. It is not the normal retry button.
- **Retry failed updates** appears only for retryable failures from the latest run. It
  releases those exact holds, runs a fresh provider scan, and selects only
  candidates that are now ordinary updates. It never starts an update; review
  the selection and use **Update selected** deliberately.

Real provider failures are treated as product feedback. When a recurring or
distinctive failure can be classified safely, WinDevPilot turns it into specific
status, durable diagnostic evidence, and bounded recovery guidance instead of
leaving a generic error or encouraging blind retries. A suggested system repair
is clearly labeled as manual and remains separate from the normal update
workflow. WinDevPilot never silently expands a selected update into
uninstall/reinstall or unrelated system changes.

The status tooltip explains why a package is recommended, blocked, held,
vendor-managed, migration-dependent, or otherwise better handled elsewhere.

### Status and safety labels

| Status | Meaning | Normal action |
|---|---|---|
| `Checking details…` | WinGet found an update and manifest preflight is still running. | Wait for the row to settle before selecting it. |
| `Pin state unavailable — review` | WinGet's pin listing could not be read reliably, so automatic selection cannot prove that the candidate is unpinned. | Scan again after checking WinGet; review the row manually rather than treating it as recommended. |
| `Updates itself` | The app's vendor updater is the safer servicing route. | Use the app's own updater. |
| `Scope or installer mismatch - held` | The exact candidate previously had no installer for this scope or technology. | Review Package details; use **Test once** only after the installation identity changes. |
| `Verification conflict - held` | The provider reported success, but a fresh scan still offered the identical update. | Wait for provider metadata to change, or use **Test once** only for a deliberate diagnostic retry. |
| `Restart required before final verification` | The just-finished update reported that Windows must restart before its result can be judged. | Restart Windows; do not retry the same offer first. |
| `Restart required to finish previous attempt` | A provider-reported update cannot be verified until Windows starts under a later boot. | Restart Windows; the next complete provider scan will resolve or hold the candidate. |
| `Newer update available after successful attempt` | The previous target disappeared and a numerically newer target is now offered. | Review the newly offered version as a separate update. |
| `Installed version unchanged after reported success - held` | The provider reported success and changed its offered target, but fresh inventory shows that the installed version did not advance. | Review Package details; do not assume the earlier target installed successfully. |
| `Available target changed after successful attempt` | The provider changed a non-numeric or non-orderable target after the attempt. | Review the new target; WinDevPilot does not guess that it is newer. |
| `Installed state changed after attempt - held` | The installed version changed, but the same target remains offered after a failed attempt. | Review Package details before using **Test once** deliberately. |
| `Provider is disabled or unavailable` | The manager that owns an attempted package could not participate in verification. | Re-enable or repair that provider, then scan again. |
| `Manual portable update available` | A newer release was found, but replacing the chosen portable layout is intentionally manual. | Right-click and copy the vetted manual-update page URL. |
| `Existing install permissions need repair` | WinGet reached the right package but could not read or replace an existing package file. | Review Package details and create the narrowly scoped repair script if appropriate. |
| `Packaged service needs administrator - held` | Windows rejected an MSIX packaged service with `0x80073D28`; even a user-scoped app can contain a service requiring administrator privileges. | Review the supported updater/installer with administrator assistance while preserving the owning account. WinDevPilot does not change scope or move a user package into the machine batch. |

## Suggested installs and Toolchain Health

**Suggested installs** lists a curated selection of developer tools not found
in WinGet's user/machine inventory. It can copy exact WinGet commands, or
right-click one suggestion to install it through WinGet. Successful installs
refresh the process PATH, the package views, and an open Toolchain Health window.

**Toolchain Health** is a non-mutating snapshot of common developer command
paths and versions, with a short explanation of each tool. It does not inspect
project folders or virtual environments. WinDevPilot refreshes its own PATH
from Windows settings and can append verified standard locations for installed
WinGet, Rust, Ninja, or PowerShell tools without editing the saved Windows
environment. When that recovery is needed, the panel labels the affected tools
and explains that the persistent user PATH still needs repair. A scan with
unavailable core or known-installed provider coverage is marked incomplete and
cannot present an “Everything is up to date” result. The same rule applies when
a provider launches successfully but only some requested scopes or its native
inventory can be read: useful rows may remain visible, but that phase is not
treated as complete evidence.

## Account-aware elevation

Launch WinDevPilot from the account whose user-scoped tools you want to
inspect and update. That account may itself belong to the Administrators group;
Windows normally launches it with a filtered token. Starting the GUI under a
*different* administrator identity changes the user profile, HKCU registry,
package-manager homes, Python user site, settings, and logs being inspected.

Normal operation is:

1. User-scoped providers run as the signed-in account.
2. Eligible machine-scoped WinGet and Chocolatey work is collected separately.
3. If the process is already elevated, that machine batch runs directly.
   Otherwise WinDevPilot requests one UAC consent or credential prompt.
4. Microsoft Store inventory and updates always stay in the account that
   launched WinDevPilot and never enter a separately launched elevated helper.

The short-lived helper reports each machine package as it starts and
finishes, rather than returning only after the complete batch. Long-running
installers emit restrained progress reminders; after 90 seconds, the message
also notes that the installer may be waiting for its application to close.
The parent accepts the named-pipe connection only when Windows reports the
client as the process ID returned by the exact elevated launch. The helper also
requires Windows to report the launching parent as the pipe server before it
receives the hash-bound plan. No credential, temporary plan file, inherited
handle, or reusable channel key crosses UAC.

Maintainers can exercise that real transport without borrowing a package update
by running `Run-WinDevPilot.cmd --elevation-smoke-test`. The command sends an
exact no-op plan, requires a genuine administrator token, and performs no scan
or package operation. Choosing a different administrator at the credential
prompt also checks that machine's cross-account named-pipe policy.

The app does not use WinGet `--force`, bypass installer hashes, disable malware
checks, ignore pin safety, or opt into automatic restarts.

WinGet pins are read during scans without changing them. Ordinary and blocking
pins simply leave the matching package unchanged with the compact status
**Pinned — left unchanged**; they add no prompt or new decision. Version-gated
pins remain governed by WinGet's permitted version range. If the pin listing is
unavailable or untrustworthy, WinGet candidates remain visible but unchecked as
**Pin state unavailable — review** until a later scan reads the pin state safely.

## Providers

Enable or disable providers from **Providers**. Unavailable managers are shown
but cannot be enabled. pip, Cargo installed crates, and vcpkg are off by
default.

| Provider | Default | Scope |
|---|---:|---|
| WinGet | On | current user and exact machine inventory from the community catalog |
| Microsoft Store | On | Store-signed apps, games, and components for the launching Windows account |
| npm global packages | On | current user |
| Bun global packages | On | current user |
| Scoop | On | current user; runs `scoop update` at most once per 10 minutes, refreshing Scoop's own core scripts and bucket indexes |
| Cargo installed crates | Off | current user |
| vcpkg classic packages | Off | current context; manual review; a manifest-only install is reported as not globally configured |
| Rustup toolchains | On | current user |
| pip user site | Off | current user |
| pipx apps | On | isolated current-user tools |
| .NET global tools | On | current user |
| uv tools | On | isolated current-user tools |
| Chocolatey | On when available | elevated machine batch |
| Windows PowerShell 5.x modules | On | `CurrentUser` only |
| PowerShell 7 resources | On when supported | `CurrentUser` only |

Windows PowerShell 5 updates check whether the loaded PowerShellGet supports
`AcceptLicense` before supplying it. Older versions retain their native license
handling; errors requiring manual action remain visible. WinDevPilot does not
upgrade PowerShellGet automatically or start an interactive fallback.

Scoop is the one provider whose discovery refresh can modify its manager: the
throttled `scoop update` refreshes Scoop's core scripts and bucket repositories
so `scoop status` does not compare installed apps against stale manifests. It
does not update installed Scoop apps. This is disclosed because it is broader
than a strictly read-only query.
If that refresh fails, its warning remains visible on subsequent scans using
the throttled cached metadata, until a refresh succeeds; no extra calls are made.

The Microsoft Store provider combines two supported views: Windows
PackageManager supplies the complete Store-signed package inventory for the
current account, while WinGet's `msstore` source supplies exact catalog product
IDs and selective update candidates. Entries that the public catalog cannot
correlate remain useful inventory; their context menu opens either a Store
search or the Store updates page. Store work is never moved into another
administrator identity. Missing optional installation dates remain unknown and
do not discard packages or abort enumeration; genuine query failures still mark
the inventory incomplete. If a Store catalog row correlates only to a
machine-wide desktop EXE/MSI registration, WinDevPilot suppresses it from the
Updates view, records the rejected catalog evidence in the structured provider
scan log, and refuses to construct a Store update command: the account,
delivery channel, and version scheme are not proven compatible.

Project dependency graphs are outside the app's scope. WinDevPilot does not
scan local `.venv` environments, Bun projects, Cargo workspaces, or vcpkg
manifest-mode projects.

### pip warnings

pip can return success while changing dependencies or leaving conflicts in the
shared user site. WinDevPilot verifies the requested target separately and
reports dependency, conflict, and PATH warnings compactly. The structured log
keeps fuller evidence and suggests `pip show` / `pip check` commands when manual
inspection is useful. npm receives a similarly conservative structural
post-check: the installed target version and declared command files are checked
without running newly installed scripts.

## Logs, diagnostics, and privacy

The lower log pane is the primary result surface. Green markers indicate
success, orange indicates warnings or review, and red indicates failure or
cancellation. Normal summaries omit meaningless zero-count categories.

Local data is stored under:

```text
%LOCALAPPDATA%\WinDevPilot\settings.json
%LOCALAPPDATA%\WinDevPilot\portable-inventory-v1.json
%LOCALAPPDATA%\WinDevPilot\installed-inventory-v1.json
%LOCALAPPDATA%\WinDevPilot\logs\session-*.log
%LOCALAPPDATA%\WinDevPilot\logs\session-*.jsonl
%LOCALAPPDATA%\WinDevPilot\diagnostic-bundles\WinDevPilot-diagnostics-*.zip
%LOCALAPPDATA%\WinDevPilot\last-crash.log
```

Keep a separate copy of this data if you value the accumulated installation
history. Graphics caches are disposable; installation receipts and observation
windows are not. The optional developer utility
[WinDevPilot_HistoryBackup.py](Tools/WinDevPilot_HistoryBackup.py) makes verified local
backups and prepares a conservative merge without changing live files. See its
[recovery instructions](Tools/WinDevPilot_HistoryBackup_README.md). Close the app first;
copy backups to another drive if you also need protection against drive failure.

System reports are created only on request at the path selected in the Save As
dialog. They may contain user/profile or application paths, so review a report
before sharing it. Reports are atomically published and capped at 16 MiB.

Provider command capture retains at most 16 MiB of raw stdout/stderr in memory,
with no output-spooling files. It keeps draining a verbose child until the
command finishes or reaches its existing timeout; exceeding the capture limit
does not itself interrupt an installer. Oversized or unreadable output is not
used as inventory or proof of success. The result says **Output incomplete —
verify before retrying**, and diagnostics distinguish the provider's actual
exit code from WinDevPilot's capture error. Retained excerpts are redacted and
subject to the separate 200,000-character diagnostic limit; their hashes are
explicitly labelled as excerpt hashes rather than hashes of unseen output.

In `--debug` mode, **Diagnostic bundle** creates a local zip and copies its
path. It includes the human log, structured trace, visible package evidence, a
redacted settings summary, and a small explanatory README. It deliberately
excludes the program's Python source, never uploads anything, and refuses to
publish an archive larger than 32 MiB.

WinDevPilot has no telemetry. Network access comes from enabled package
managers and their required metadata services, such as WinGet sources, npm,
PyPI, NuGet, crates.io/rustup, Chocolatey, and PowerShell Gallery.

`Run-WinDevPilot.cmd scan-json` performs the same non-installing update and
installed-package discovery used by the GUI. Its schema includes `updates`,
`installed_packages`, portable-cache counts (with portable records and
advisories folded into the two ordinary package arrays), provider warnings and
incomplete-phase errors, and attempt-hold summary data. It does not install,
update, or remove managed app packages; when Scoop is enabled, its documented
throttled core-and-bucket refresh still applies.

## Boundaries and practical limits

WinDevPilot is a local, interactive update companion—not a replacement for the
package managers underneath it, an unattended fleet-patching service, or a
project dependency manager. Its conservative boundaries are part of the product:
when the available evidence cannot support an exact action, the app leaves the
decision visible instead of manufacturing certainty.

- A vendor installer can still ignore silent flags or require an application to
  be closed.
- Some Store components and vendor-managed apps are correctly left unchecked
  because Windows servicing or the owning application is the safer updater.
- Duplicate user/machine installs and installer-technology migrations require
  review rather than forced retries.
- WinGet output is human-readable and localization can reduce parser coverage.
- WinGet discovery capability-probes for structured JSON output and validates
  its schema when a future installed version advertises it. Otherwise two
  independent views of each fixed-width table—column geometry and whitespace
  tokens—must agree. Zero parsed rows count as current evidence only when an
  empty structured array or WinGet's dedicated no-applications result proves
  emptiness; every other unfamiliar zero-row response marks that provider phase
  incomplete. Update candidates must also reconcile with a separate installed-
  inventory read. The exact native no-match sentence from an otherwise
  successful unfiltered upgrade inventory is also accepted as affirmative
  empty evidence; mixed, silent, localized, or unfamiliar zero-row output still
  fails closed. Ambiguous data is shown unchecked or discarded instead of
  guessed. No PowerShell WinGet module or COM dependency is needed.
- Portable PE version resources are read without loading or executing their
  binaries. Before Python dereferences a `VerQueryValueW` result, WinDevPilot
  verifies that its complete byte range stays inside the exact buffer supplied
  to Windows and applies structure-specific length limits.
- During an update/install/uninstall run, cancel means **stop after the current
  package**; the app does not normally kill an installer in mid-transaction.
  A machine batch already handed across the one-prompt elevation boundary may
  finish its validated items; the status line says so instead of promising
  that the helper can be recalled.
  During a scan, it stops queued providers and marks the completed providers'
  partial result set as stale.
- WinDevPilot does not automatically repair registry inventory, migrate
  scope, clean duplicate installations, or perform uninstall/reinstall
  migrations.
- A Rustup rollback caused by a missing recorded component file is classified
  as a damaged toolchain and held for manual reinstall guidance rather than
  repeatedly offered as an ordinary update.

## Learn more and contribute

- Read [CHANGELOG.md](CHANGELOG.md) for the release candidate's user-visible
  additions, changes, and fixes.
- See [CONTRIBUTING.md](CONTRIBUTING.md) for issue reports and contribution
  expectations.
- Use [BuildInstructions.md](BuildInstructions.md) for the maintainer environment
  and validation commands.
- Consult [WinDevPilot_PROJECT_NOTES.md](Docs/WinDevPilot_PROJECT_NOTES.md) for the
  architecture, safety invariants, and deeper implementation notes.

## License

WinDevPilot is available under the [MIT License](LICENSE).

## Vector authoring update

The inline software renderer and standalone VectorWorkshop now share define-only
templates, bounded assemblies of earlier parts, and positioned gradient stops.
Pivot-to-target placement and bounded repeated transforms further shorten shared
geometry. Incremental geometry caching is exclusive to the standalone Workshop;
WinDevPilot keeps its existing bitmap-cache workflow.
Workshop offers undoable authoring controls and selectable examples. Existing
icons retain identical artwork with slightly shorter source; genuine retrieved
artwork still takes precedence unless a documented identity-specific override applies.


## September 2026 review corrections

A disappearing update offer is no longer sufficient to record a verified service
history entry. Final verification requires fresh inventory from the attempted
provider and an unambiguous match of package ID, source, scope, registration and
installed target version. Inconclusive or reboot-dependent results stay unverified.
Concurrent scans can show successor releases while the recorded attempt retains
the originally confirmed versions. Installer cancellation is counted as cancellation.

Successful uninstall commands initially report removal pending verification.
Installation history is retained until a fresh inventory confirms absence in the
selected scope; restart-required removals remain pending. These pending-removal
checks are session-local; closing the app retains history rather than inferring
removal. Existing command logs retain the uninstall receipt.

WinGet manifest probes request the selected version, cache successful evidence for
three minutes and do not cache failures. Chocolatey inventory detects the CLI major
version to select its local-list syntax. npm error envelopes and partial dependency
trees cannot replace previous inventory as a complete empty observation. Before
update commands begin, a worker waits up to five seconds for the confirmation logs
to flush; failed acknowledgement prevents dispatch without blocking Tk.

Generated icons survive theme changes. Changed artwork rejects stale per-item
preparations; Lineup excludes fully transparent content and retains raw bundles
under a RAM-aware 16–128 MiB budget (including unpacked PNG copies). Open windows
may retain their own images; cache eviction only removes reusable preparations.
Graphics cleaning clears those preparations and rejects their late completions.
Package Details resolves current model objects on publication while preserving
scroll position. Main-window dimensions are bounded by the monitor work area.

Distribution bundles are rebuilt only on explicit request.

Refreshes preserve existing table rows and paint log bursts in small slices. Logs follow new activity only when already at
the bottom. Details keeps its reading position when artwork arrives and includes
status and guidance outside debug mode.

Each fresh provider records its own observation interval. Date windows use the
previous observation's start and the new observation's finish; another provider's
delay cannot make old evidence fresh. Duplicate or changed registrations and
unknown installed versions interrupt continuity. Inventory cache schema 5 retains
these intervals; earlier cache schemas remain readable but need a new baseline
before supplying new transition windows. Original history receipts are preserved.
Service-date sorting follows the displayed day, and a demonstrably later current-
version transition can take precedence over an older verified action.

Command execution and output collection have separate deadlines. After process
exit, output gets up to two seconds to finish; a descendant retaining the pipe
then produces an incomplete-capture result with the native exit code preserved.
It is not labelled an installer execution timeout and does not authorize a retry.
WinGet retries retain the selected version; an unavailable target requires a
refreshed candidate. Current-user rows distinguish installer exit, evidence
collection and installed-version checking.

The gallery attaches already-decoded artwork while creating tiles, retains
overlapping tiles while scrolling, and recycles outgoing image/name pairs for
incoming packages. Remaining icon work runs in short cooperative batches, with
at most two gallery preparation requests at once. All asynchronous icon completions
use that same pump, including its native-window-interaction and cache-clear guards.
During dragging and momentum, the whole pending band of already-decoded photos
can be assigned immediately. Image creation from validated resident PNG bytes
uses soft 1-ms slices,
with 16-ms continuations. Each slice may also request one visible cold icon from
a worker, within the existing two-job limit. Workers return validated PNG bytes
through the shared bounded catalog, allowing artwork to appear before scrolling
stops. Native window gestures and cache clearing still defer the pump; disk reads,
extraction and new vector rendering stay off the motion callback's Tk thread.
Unresolved gallery artwork leaves a quiet icon space instead of flashing a wrench.
Branded fallback art and available real list icons remain usable. A generic wrench
appears only after current negative evidence confirms missing artwork; transient
worker failures do not establish a miss. Confirmed misses retain the existing
expiry and package/generation checks.
Rapid drag events accumulate into an 8-ms scheduled scroll, preserving the final
position on release. Single clicks select; double-clicks open Details. Velocity
samples are grouped by time so fast input retains roughly 120 ms of history.
Momentum scheduling accounts for callback time and skips elapsed deadlines
without catch-up bursts. Fractional motion is retained while redundant scroll
requests within the same displayed pixel are skipped. Drag bounds are reused
between packets; viewport width or height changes cancel the gesture safely.
Elastic edge returns use the same animation scheduling and icon-loading guards;
wheel, scrollbar and keyboard positioning stay within the ordinary bounds.
Sideways dragging gives the same resisted stretch and spring return, without
horizontal scrolling. A firm 48-DIP horizontal dead zone keeps ordinary vertical
drags exactly straight. Only movement beyond it starts the sideways stretch,
without a jump; catching an existing bounce retains its current position.
Both components remain independent: diagonal pulls can
stretch at a top/bottom edge, and the sideways return continues alongside vertical
momentum or wheel travel. Icons, names and the selection outline move together;
clicks target their displayed positions and exposed whitespace is not a package.
These timers do not promise synchronization with the monitor's refresh cycle.
List scrolling also promotes
ready icons without waiting for the cold-discovery quiet period. The shared
Details-image cache has a 64-MiB estimated storage budget and a 1,024-entry ceiling,
with each DPI size charged separately; visible widgets retain their own images.
Ordinary Updates/All packages tab changes retain decoded Details artwork; forced
refreshes and explicit invalidation still discard stale entries. Final gallery
images retained by visible tiles remain usable after shared-cache eviction.

While All packages rests in list mode, a small speculative queue prepares the
opening gallery viewport plus overscan and the focused package (at most 128
targets). At rest in gallery mode it targets one page beyond the retained tiles
in the last scroll direction, reversing at an end; spare targets include retained
rows. Normal-size decoding comes first, followed by preparation of missing 5/8
copies for either gallery size. List mode continues to prepare normal images only.
Visible pending work has priority, and no speculative canvas tiles are created.
Plans use resident artwork; entries completed by foreground work are skipped
within the same turn. List-mode planning uses the displayed table's dimensions.
Preparation waits for 300 ms of quiet, with at least 40 ms between opportunities.
Gallery mode uses a soft 4-ms batch budget, checked between individual image
operations; one operation may finish just past the deadline. List mode retains
one image per opportunity. Input, native window gestures, list/gallery motion, pending rebuilds,
busy operations, cache cleaning and queued GUI events defer this work. Existing
workers carry validated PNG bytes back to the GUI; completion handlers register
bytes without decoding photos. Shared generated artwork can be promoted by the
bounded visible pump during scrolling or by idle preparation. Normal and shared
vector admission uses the 48-MiB estimate; speculation does not evict useful
images to make room. Compact photos are pinned independently. Compact preparation
uses some RAM earlier and may still be
outpaced by immediate scrolling. It performs no disk reads,
extraction or vector rendering on the Tk thread and starts no additional workers.
Fitted gallery labels use a bounded 2,048-entry memo keyed by text, font, available
space and DPI; first-time fitting retains the existing wrapping and ellipsis rules.
Recent wheel, scrollbar and keyboard input also restricts the visible gallery
pump's decoding to resident artwork, while allowing the same bounded visible-item
worker requests. Speculative preparation still waits for quiet. Search ranking skips lower-priority
fields once they cannot improve a match, preserving substring ordering.

Disk-only reads and first-time rendering can still exceed an individual batch's
soft time budget. Warm-image timings do not establish cold-start or frame-rate
guarantees.
