Table of Contents

Namespace Archiver.App.Core

Classes

ArchiveEntryViewModel

One entry in the archive browser's current folder view — a path inside an archive, distinct from FileItem (a top-level pending-selection path queued for an Archive/Extract operation). Plain, no WinUI dependency — lives here so ArchiveTreeIndex stays unit-testable without a WinUI test host.

ArchiveTree

An archive's folder tree. Many ZIPs have no explicit directory entries — folders are implied by '/' in file paths — while tar-family listings carry them; both shapes give the same tree, and the first entry at a path wins. A folder's row list is built on first request, so only visited folders pay for full-path strings (T-F237: one string per ancestor was O(depth^2)).

ArchiveTreeIndex

Builds an ArchiveTree from a flat ArchiveEntryInfo list, once per archive open. Lives in Archiver.App.Core (not Archiver.Core) because Archiver.Core has zero WinUI/UI-model references — a folder hierarchy is an App-layer concern.

BrowseLocationState

T-F199 step 6 / T-F210: what the Archive Browser offers where the user is. Inside an archive: the extract actions and their options; Test only for ZIP (tar.exe has no test mode, and Explorer offers Test for ZIP only); "delete after" only for an archive on disk, not a nested one (that is a temp copy). Outside (a real folder or "This PC" after Up, T-F107): none of it, and a line saying where the user is.

BrowseNavigation

T-F112: the Archive Browser's Up decision, out of the WinUI view model so it is testable.

BrowseWork

T-F199 step 6: counts browse work that runs without IsBusy (listing, nested drill-in, preview). "Close archive" stays off while any is in flight, or the work would finish into a closed browser (fill the index, push a nested level) after the user left.

BrowserEntryRouting

T-F242 items 3, 4 and 6: the double-click decisions of the pending list and the Archive Browser, and the containment check for a file extracted into a temp scope.

BuildStamp

The window title's build stamp — the proof every on-device check starts from that the running binary is the one just built (CLAUDE.md). T-F218: the compile time from the assembly's PakkoBuildTimeUtc metadata, not the packaged DLL's file time (the MSIX install time). T-F198 item 4: a Store build shows no stamp.

ConflictText

The size and date lines of the App's conflict dialog (T-F220 item 2), in the shape the Explorer operation window uses. The App sets the "modified" word once at startup; English until then.

CreateModeText

T-F199 step 4: the create-mode words that follow the list and the options. Returns resource keys (plain, read through GetString — T-F104), never text.

DeferredActionGate

Runs actions immediately once "opened," queues them (FIFO) beforehand. Backs MainWindow's "don't mutate FileItems before the root Grid's first Loaded/layout pass" fix (T-F106) — kept WinUI-free (mirrors FileActivationRouter's split) so the queue/flush logic itself is unit-testable even though the actual trigger (Loaded) isn't. Open() is idempotent — a second call is a no-op, not a re-flush.

DisplayText

The words the App's lists show for items (T-F198): a folder's type, a file without an extension, and size units. App.Core has no resource loader, so the App sets them once at startup from its own resources; until then they are English, which is what the tests see.

DownloadMarkOption

T-F360: the extract wizard offers to leave an archive's download mark off the extracted files. Shown only when extraction is the action and an archive carries the mark; an EnforceMOTW Group Policy locks it to the policy's mode.

EncryptionSummary

T-F199 (browse mode): the "encrypted" badge and info panel for an archive, read from the listing without a password (T-F202: nothing showed the archive was encrypted until a password was asked for).

FileActivationDecision

Result of Decide(IReadOnlyList<string>).

FileActivationRouter

Decides whether a File-kind activation should enter the Archive Browser (T-F05) or fall back to the existing "add these paths to the pending archive-creation list" behavior. Lives in Archiver.App.Core (not Archiver.App) so the decision is unit-testable without a WinUI test host — mirrors ArchiveTreeIndex's split for the same reason.

FileItem

One top-level path in the pending archive-creation/extraction list, with its size and CRC-32 computed in the background. Disposing it (the row was removed) stops that work.

FileSystemBrowser

Lists real Windows filesystem folders/drives for the Archive Browser's "climb past the archive root" navigation (T-F107) — reuses ArchiveEntryViewModel unchanged (its optional CompressedSize/Crc32 fields already render as "not applicable" for a plain file/folder). Lives in Archiver.App.Core, not Archiver.App, for the same reason ArchiveTreeIndex does: unit-testable without a WinUI test host.

FooterLine

The footer's first-line precedence: busy, then the outcome, then browse selection, then the preview.

HashReport

T-F219: what the App's "Hash..." hashes and how its result is named and copied. SHA-256 only (T-F164, user decision, confirmed again for T-F219).

InlinePasswordState

T-F199: the encryption password typed inline under the checkbox, checked while typing with Core's EncryptionPasswordRule. Like a Windows PIN box, a field keeps only allowed characters; a refused one blocks until that field is emptied, because in a Ukrainian layout the ASCII left over in both fields would still match. Holds the text only while the window needs it: the caller clears it after the operation, when encryption is turned off, when the format changes and when the window closes; nothing is persisted or logged.

LaunchActivationDecision

Result of Decide(string?).

LaunchActivationRouter

Routes a Launch-kind activation carrying Archiver.Shell's LaunchArguments (T-F232, replacing the pakko:// protocol route of T-F03/T-F56). --browse with exactly one file enters the Archive Browser; anything else parsed adds its paths to the pending list — the same one-archive-only browse rule FileActivationRouter applies.

ListActions

What the list allows, and which action the window emphasizes.

NestedArchiveCache

T-F98: temp cache for the Archive Browser's nested-archive drill-down, one Guid subfolder per nesting level extracted so far — mirrors PreviewCache's shape, but adds DeleteScope for immediate per-level cleanup on navigating back out. That's safe here (unlike PreviewCache, which must wait for window close since an external OS handler may still have the previewed file open): nothing outside Pakko ever holds a handle into a nested-archive scope once the user leaves that level. T-F252: one subfolder per process (ProcessTempRoot).

NestedArchivePolicy

T-F98: bounds how many nested archives the Archive Browser will drill into, one inside another. This is a browse-session/UX resource bound enforced by the App layer's recursive orchestration, not a per-extraction security invariant — that backstop is T-F49 (whole-archive pre-scan) and T-F90/T-F94 (compression-ratio + disk-space check), already in Archiver.Core and already re-applied independently at every nesting level since each level goes through the same IExtractionRouter.ExtractAsync pipeline. See DECISIONS.md's T-F98 entry for why 4 was chosen.

NestedDisplayPath

T-F220 item 5: a nested archive is browsed from a temp copy (NestedArchiveCache); text shown to the user names the chain the user drilled through instead of that copy's path.

OutcomeLine

T-F211: the result line the footer keeps until the next action (it used to be overwritten by "Ready" a moment after the operation ended, so a clean run showed nothing).

PendingPaths

T-F278: which dropped or picked paths join the pending list. Windows paths are not case-sensitive, so C:\a\File.txt and c:\a\file.txt are the same item.

PreviewCache

T-F97: temp cache for Archive Browser file previews, mirroring TarSandboxScope's "%TEMP%\Pakko<Purpose>" convention (Archiver.Core/Services/Sandbox) but kept in the App.Core layer since preview staging is a pure App-layer concern. T-F252: one subfolder per process (ProcessTempRoot).

PrimaryActionPolicy

T-F199 (option A, user decision 2026-09-27): two action buttons, the accent on the one that fits the list — archives only: Extract, anything else: Compress. T-F212: Extract runs only on items that are archives Pakko may open; canOpen is Core's ArchiveFormatPolicy.CanOpenByExtension (policy, tar.exe, no disk I/O).

ProcessTempRoot

T-F252: one shared %TEMP% root with a subfolder per Pakko process. Pakko is multi-process by design (T-F88), so a window may delete only its own subfolder; SweepStale() removes the subfolders of processes that are gone (a crash or a kill leaves previewed plaintext behind).

ProgressText

The footer's speed and time left during an operation (T-F303), in the same localized units as the list's sizes (DisplayText). App.Core has no resource loader, so the App sets the words once at startup; until then they are English, which is what the tests see.

RecoveryDataOption

T-F275: the "New archive" card's option to write PAR2 recovery data next to the archive — 5, 10 or 20 % (default 5), hidden by the DisableRecoveryData policy.

RecoveryPanel

T-F275 step 3c: the Archive Browser's line about the PAR2 files next to the open archive. Before a test it says only that files were found (whether they are usable is known after the test); after a test it carries Core's verdict for that archive. Pure, so the rules are tested without a window.

RecycleResult

What DeleteAsync(IEnumerable<string>, Func<IReadOnlyList<string>, Task<bool>>) did, by the paths given (T-F302).

SessionPasswordMemory

T-F200: the Archive Browser remembers a password that worked for an archive, so previewing a second file, drilling into a nested archive or extracting again does not ask again. Held in memory for the browse session only: cleared when another archive is opened, when browsing ends and when the window closes; never written anywhere.

SortIndicator

T-F220 item 4: the arrow a column header shows once the list is sorted by it — Segoe MDL2 ChevronUp (ascending) or ChevronDown (descending); nothing on the other columns, and nothing before the first click (the list keeps the order items were added in until then).

SourceRecycler

"Delete after operation" (T-F207): recycles sources on a fixed local volume, asks before permanently deleting anything else, and reports what is still on disk.

Win32PakkoWindows

T-F201: top-left corners of the visible top-level windows of other Pakko App processes, for WindowCascade.

Win32SourceDeleteOperations

Real ISourceDeleteOperations over Win32 (T-F207).

WindowCascade

T-F201: Pakko is multi-instance by design (T-F88), and every new window opened at the same default spot, exactly over the one already open. Cascades a new window's top-left corner off every other Pakko window, staying inside the work area.

Structs

DownloadMarkView

What the download-mark checkbox shows (T-F360).

Interfaces

ISourceDeleteOperations

The platform operations SourceRecycler needs, behind an interface so its decisions are testable without touching the real Recycle Bin.

Enums

ArchiveBrowseScope

T-F107: what the Archive Browser's current folder path means. Archive: a '/'-separated path inside the open archive. RealFileSystem: an absolute Windows folder. ThisPc: the drives list; the path is unused.

BrowseListFailureStep

T-F319: where the browser goes when an archive that was just opened fails to list.

BrowseUpStep

Where Up goes from the current location.

DownloadMarkNote

The text under the download-mark checkbox.

FileActivationMode

What a File-kind activation should do, per Decide(IReadOnlyList<string>).

FooterLineKind

What the footer's first line shows (T-F199 step 7).

InlinePasswordIssue

What stops an inline encryption password from being used.

PrimaryAction

The two actions the main window offers for its list.

RecoveryPanelSeverity

How the recovery line reads at a glance; the App maps it to an InfoBar severity.

RowOpenAction

What double-clicking a row does (T-F242 item 3: this was decided in code-behind).