Update design docs

This commit is contained in:
John Burwell 2026-06-01 15:04:20 -05:00
parent cbcbf85538
commit 5562389b1c
3 changed files with 362 additions and 236 deletions

View File

@ -1,136 +1,105 @@
# iOS Device Access Notes
# Connected iOS Device Access
## Summary
This project can now read Minecraft Bedrock content directly from a connected iPhone or iPad on macOS using `MobileDevice.framework` and House Arrest.
World Manager can browse Minecraft Bedrock content from a trusted iPhone or iPad on macOS using Apple's private `MobileDevice.framework` and the House Arrest service.
The app does **not** scan the device live through custom file APIs. Instead, it:
Connected-device sources are modeled as normal `MinecraftSource` values, but they are not scanned through a live filesystem mirror. The current implementation asks the device for library item summaries, metadata, icons, sizes, and directory listings through `AppleMobileDeviceSourceAccess`. Only explicit materialization operations, such as reveal/export/share, mirror an item subtree into a temporary local directory.
1. Detects a connected trusted device with `MobileDevice.framework`.
2. Opens House Arrest for `com.mojang.minecraftpe`.
3. Uses `VendDocuments`.
4. Mirrors the proven Minecraft subtree into a temporary local folder.
5. Hands that local folder to the existing `WorldScanner`.
## Current Flow
That keeps the rest of the app filesystem-based.
1. `SourceLibrary` owns a `ConnectedDeviceRuntime` refresh loop when a connected-device access method is configured.
2. `AppleMobileDeviceSourceAccess.listConnectedDevices()` enumerates devices through `AppleMobileDeviceAccess.connectedDevices()`.
3. `AppleMobileDeviceSourceAccess.listAccessibleContainers(for:)` lists app containers and prioritizes `com.mojang.minecraftpe`.
4. `ConnectedDeviceSourcePickerView` lets the user add a device-backed Minecraft source.
5. `ConnectedDeviceSourceFactory` creates a stable synthetic source identifier:
## Proven Findings
```text
wmminecraft-device://<device-udid>/<bundle-id>?mode=documents
```
### Correct bundle ID
6. `SourceScanExecutor` scans the source through the generic `SourceAccessMethod` protocol.
7. `AppleMobileDeviceSourceAccess.discoverItems` calls `minecraftLibrarySnapshot` for item summaries and `minecraftMetadataBatch` for metadata.
8. Preview icons, size metrics, directory contents, and full item materialization are loaded lazily through the same source-access method.
Minecraft on the tested device is:
This keeps UI, indexing, export, and persistence mostly source-agnostic while allowing connected devices to avoid a full upfront mirror.
- `com.mojang.minecraftpe`
## Minecraft Container
### App metadata
The tested Minecraft bundle identifier is:
The app record reported:
```text
com.mojang.minecraftpe
```
- `UIFileSharingEnabled = 1`
- `LSSupportsOpeningDocumentsInPlace = 1`
Minecraft exposes a vendable Documents surface. The working Minecraft content root for House Arrest `VendDocuments` is:
So Minecraft does expose a vendable Documents surface.
```text
Documents/games/com.mojang
```
### Correct vend root
The app treats that value as a vend-relative path stored on `DeviceAppContainer.minecraftFolderRelativePath`.
House Arrest `VendDocuments` succeeds, but the Minecraft content is **not** rooted at:
Expected subfolders under that root:
- `games/com.mojang`
- `minecraftWorlds`
- `resource_packs`
- `behavior_packs`
- `skin_packs`
- `world_templates`
The proven path is:
## House Arrest Details
- `Documents/games/com.mojang`
The implementation uses the explicit House Arrest flow in the Objective-C bridge:
### Proven subfolders
1. Start `com.apple.mobile.house_arrest`.
2. Send `VendDocuments`.
3. Receive the vend response.
4. Use AFC against the returned service connection.
These paths were verified through AFC on the real device:
The direct `AMDeviceCreateHouseArrestService` helper returned `InstallationLookupFailed` / `e80000b7` on the tested device, so it is not the primary path.
- `Documents/games/com.mojang/minecraftWorlds`
- `Documents/games/com.mojang/resource_packs`
- `Documents/games/com.mojang/behavior_packs`
- `Documents/games/com.mojang/world_templates`
The AFC root for this vend should not be treated as a normal `/` filesystem root. Paths are relative to the vend surface, and Minecraft content is reached through `Documents/games/com.mojang`.
## Important API Findings
## Runtime Behavior
### `AMDeviceCreateHouseArrestService`
Connected-device sources use a staged refresh strategy:
The direct helper path still returned a device-side error on the tested device:
- Availability is derived from current device presence and trust state.
- Trusted devices are available.
- Locked or untrusted devices are limited.
- Missing or inaccessible devices are disconnected.
- When a source becomes available, `SourceSyncRuntime` can queue a reconcile scan instead of a full scan if cached content exists.
- `InstallationLookupFailed`
- `e80000b7`
Scan execution uses fewer workers for connected-device sources than local folders to avoid overloading AFC/MobileDevice calls.
So the app currently relies on the explicit vend flow instead:
During scan:
1. `AMDeviceSecureStartService("com.apple.mobile.house_arrest")`
2. `AMDServiceConnectionSendMessage` with `VendDocuments`
3. `AMDServiceConnectionReceiveMessage`
4. Create AFC from the returned service connection
- `minecraftLibrarySnapshot` returns candidate content items.
- `minecraftMetadataBatch` returns display names, UUIDs, versions, minimum engine versions, and world pack references.
- Icons are loaded with `minecraftIconBatch` or individual file reads and cached through `ImageCacheStore`.
- Size information is loaded through `pathMetricsBatch`.
- Directory previews call `listDirectory`.
### `VendDocuments` vs `VendContainer`
During materialization:
`VendDocuments` is the working path for Minecraft on the tested device.
- `materializeItem` mirrors one remote item subtree into `NSTemporaryDirectory()/WMMConnectedDeviceReveal/...`.
- `ContentPackageExporter` mirrors the selected item into archive staging when exporting connected-device content.
- Temporary materialized folders are treated as disposable.
### AFC path behavior
## Persistence
The AFC root is not a normal `/` root for this vend. Examples:
Connected-device sources are persisted in the SQLite source cache with:
- `"/"` returned AFC status `0xA`
- `"/games/com.mojang"` returned AFC status `0x8`
- `"Documents/games/com.mojang"` worked
- source identifier
- source origin and device/container metadata
- access descriptor
- availability
- raw item cache
- source snapshot
- last scan date
So code should use the proven vend-relative path instead of assuming a container root layout.
## Current Project Shape
## Source Access Architecture
Source intake is now organized around access methods rather than one-off services.
- `SourceAccess/Core`
- shared contracts and the `SourceAccessCoordinator`
- `SourceAccess/LocalFolder`
- the local disk access method
- `SourceAccess/ConnectedDevice`
- connected-device source creation and picker UI
- `SourceAccess/ConnectedDevice/AppleMobileDevice`
- the built-in Apple mobile-device transport
The key abstraction is `SourceAccessMethod`.
Each access method is responsible for:
1. turning a `MinecraftSource` into a local `PreparedScanRoot`
2. cleaning up that prepared root when scanning finishes
That keeps the rest of the app indifferent to how a source is reached.
### App path
User flow:
- `SourcesSidebarView` opens the connected-device sheet.
- `ConnectedDeviceSourcePickerView` lets the user select a device/app and a subpath.
- `AppleMobileDeviceSourceAccess` is the active connected-device access method.
### Scan-root preparation
`SourceAccessCoordinator` chooses between:
- local folder sources
- connected device sources
For connected devices:
- the built-in `AppleMobileDeviceSourceAccess`
- future connected-device access methods can implement the same contracts
### Mirror behavior
The MobileDevice fallback:
- mirrors the subtree into a temporary directory
- returns that directory as `PreparedScanRoot.rootURL`
- cleans it up with `CleanupBehavior.deleteTemporaryDirectory`
On app launch, cached sources and items are restored before availability refreshes complete, so offline device-backed sources can still show cached results.
## Relevant Files
@ -138,19 +107,14 @@ The MobileDevice fallback:
- `World Manager for Minecraft/SourceAccess/ConnectedDevice/AppleMobileDevice/AppleMobileDeviceBridge.h`
- `World Manager for Minecraft/SourceAccess/ConnectedDevice/AppleMobileDevice/AppleMobileDeviceAccess.swift`
- `World Manager for Minecraft/SourceAccess/ConnectedDevice/AppleMobileDevice/AppleMobileDeviceSourceAccess.swift`
- `World Manager for Minecraft/SourceAccess/Core/SourceAccessCoordinator.swift`
- `World Manager for Minecraft/SourceAccess/LocalFolder/LocalFolderSourceAccess.swift`
- `World Manager for Minecraft/Models/SourceOrigin.swift`
- `World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourceFactory.swift`
- `World Manager for Minecraft/SourceAccess/ConnectedDevice/ConnectedDeviceSourcePickerView.swift`
- `World Manager for Minecraft/Services/Sources/ConnectedDevice/SourceConnectedDeviceRuntime.swift`
- `World Manager for Minecraft/Services/Sources/Scanning/SourceScanExecution.swift`
## Developer CLI
## Developer Probe
A local probe harness was added for iteration:
- `Scripts/run_mobile_device_probe.sh`
- `Tools/mobile_device_probe.m`
Useful commands:
The local probe harness is useful for debugging MobileDevice behavior outside the app:
```sh
Scripts/run_mobile_device_probe.sh summary
@ -160,18 +124,11 @@ Scripts/run_mobile_device_probe.sh probe-paths com.mojang.minecraftpe
Scripts/run_mobile_device_probe.sh mirror com.mojang.minecraftpe 'Documents/games/com.mojang' /tmp/wmm-minecraft-device-mirror
```
These commands generally need to run outside the agent sandbox to access the real connected device.
These commands require a trusted connected device and generally need to run outside restricted automation sandboxes.
## Known Cleanup Targets
## Caveats
Not part of the device-access implementation itself:
- `layoutSubtreeIfNeeded` warning: SwiftUI/AppKit layout issue
- `duplicate column name: bookmark_data`: persistence migration issue
- preview actor-isolation warnings in `PreviewFixtures.swift`
## Recommendation
Keep the CLI probe and this document.
They provide a reproducible path for future device-access debugging without going back through GUI-based experimentation.
- `MobileDevice.framework`, House Arrest, and AFC are private Apple interfaces.
- Behavior can change across macOS, iOS, iPadOS, and Minecraft releases.
- Device access requires trust, unlock state, and a vendable app container.
- Connected-device export/reveal operations may be slower than local folder operations because they materialize remote content on demand.

View File

@ -1,117 +1,201 @@
# Library Intelligence Notes
# Library Architecture and Future Intelligence
## Focus Areas
## Current Architecture
- Cross-library search across all scanned sources, not just the currently selected library.
- Smart folders as saved queries over indexed content.
- Automated analysis that surfaces outliers, integrity issues, and duplicates.
- File operations for moving, copying, backing up, and restoring Minecraft content across sources.
The app is organized around source-agnostic Minecraft libraries. A source can be a local folder or a connected iOS/iPadOS device, but the UI mostly interacts with the same `MinecraftSource` and `MinecraftContentItem` models for both.
## File Operations
The main runtime owner is `SourceLibrary`:
Core operations:
- Stores visible sources and connected-device sidebar entries.
- Starts and cancels scans.
- Restores/persists cached sources.
- Refreshes source availability.
- Builds item lookup indexes for selection and file actions.
- Routes filesystem-like operations through `SourceAccessMethod`.
- Copy a world from one library to another.
- Copy packs or templates between libraries.
- Export selected items as archives.
- Import archives or folders into a target library.
- Back up an entire accessible Minecraft library from a device or folder source.
- Restore items from a backup into a chosen target source.
`ContentView` renders the three-column app:
Operational concerns:
- source/device sidebar
- projected item list
- detail/metadata/action column
- Detect duplicate world or pack identities before writing.
- Handle naming conflicts with overwrite, rename, or skip behavior.
- Validate that the destination source supports the content being copied.
- Show progress for long-running copy or backup work.
- Keep operations source-agnostic where possible so local folders, connected devices, and removable media can share the same workflow.
The item list is built from an `ItemCollectionProjectionRequest` and generated off the main actor by `ItemCollectionProjector`.
Future file-operation ideas:
## Source Access
- Batch copy selected worlds or packs.
- Sync or compare two libraries before copying.
- One-click backup of a connected device's Minecraft content.
- Backup manifests so backups remain browsable and restorable later.
- Restore preview showing what will be created or overwritten.
`SourceAccessMethod` is the boundary between source-specific I/O and source-independent app behavior.
## Cross-Library Search
The protocol covers:
Goals:
- access descriptor
- availability
- capabilities
- discovery
- enrichment
- preview assets
- size loading
- directory listing
- item materialization
- cache cleanup
- Search across every scanned source in one place.
- Show which library or device each result came from.
- Keep search useful even when some device-backed sources are offline by using cached scan results where possible.
Implemented access methods:
Useful filters:
- `LocalFolderSourceAccess`
- resolves security-scoped bookmarks
- scans local Minecraft folders with `WorldScanner`
- reads local directory listings
- returns native folder URLs for materialization
- Content type: worlds, behavior packs, resource packs, skin packs, templates.
- Source kind: local folders, connected devices, removable media.
- Source name or device name.
- Health state: complete, partial metadata, broken, unresolved references.
- Size ranges and date ranges.
- `AppleMobileDeviceSourceAccess`
- enumerates devices and app containers through MobileDevice
- discovers Minecraft content through device summaries and metadata batches
- loads icons, sizes, and directory contents on demand
- materializes device items by mirroring one subtree to a temporary directory
Useful result metadata:
`ContentViewDependencies.makeDefault()` wires `SourceLibrary` with a `SourceAccessCoordinator` that dispatches between local-folder access and Apple MobileDevice access.
- Display name.
- Source name.
- Content type.
- Size.
- Last played or modified date.
- Availability state for the backing source.
## Scanning Pipeline
## Smart Folders
`SourceScanExecutor` runs source scans in stages:
Definition:
1. Mark source as scanning and update availability.
2. Start a `WorldScanner` scan session.
3. Discover items through the source-access method.
4. Feed discovered items into `SourceIndexActor`.
5. Enrich metadata through worker tasks.
6. Build and publish normalized index snapshots.
7. Load preview assets.
8. Load size metrics for local sources; connected-device size loading uses a faster batched path.
9. Persist source state after major stages.
10. Update final status and send scan notifications when appropriate.
- Smart folders are saved predicates over indexed content, not physical folders on disk.
Local reconcile scans can reuse cached items for unchanged collection snapshots. Connected-device reconcile scans preserve cached collections when a device response omits a collection that was previously known.
Built-in smart folder candidates:
## Content Model
- Largest Worlds
- Largest Archives
- Recently Modified
- Recently Played
- Broken Archives
- Worlds With Missing Packs
- Duplicate Packs
- Suspicious Packs
- Offline Results
- Incomplete Metadata
The app recognizes these content types:
Future direction:
- worlds: `minecraftWorlds`
- behavior packs: `behavior_packs`
- resource packs: `resource_packs`
- skin packs: `skin_packs`
- world templates: `world_templates`
- Allow users to create custom smart folders from filters and sort rules.
`MinecraftContentItem` stores:
## Automated Analysis
- stable folder URL identity
- content type and collection root
- display name and icon
- dates and size
- pack UUID/version/engine metadata
- world metadata from `level.dat`
- pack references
- metadata/preview/size loading flags
Potential analyses:
`WorldScanner` handles local folder discovery and enrichment:
- Largest content items by size.
- Broken archives or invalid package structures.
- Worlds missing `level.dat` or other expected files.
- Worlds with unresolved pack references.
- Duplicate packs across libraries by UUID and version.
- Diverged duplicates that appear related but differ in size, modified date, or fingerprint.
- Orphaned packs not referenced by any world.
- Changes since the last scan.
- finds candidate collection folders
- detects embedded behavior/resource packs inside worlds
- reads `levelname.txt`, `manifest.json`, icons, and `level.dat`
- computes collection snapshots for reconcile scans
Possible outputs:
## Normalized Index
- Smart folder population.
- Sidebar badges or warnings.
- A future dashboard or “Insights” view.
`SourceContentIndexer` turns raw discovered items into normalized source data:
## Suggested Order
- `rawItems`
- `logicalPacks`
- `logicalWorlds`
- `packInstances`
- `worldPackRelationships`
- `displayItems`
- content-type counts
1. Add global search across all scanned libraries.
2. Add a small set of built-in smart folders.
3. Add integrity and duplicate analysis to feed those folders.
4. Add custom smart folders later if the built-ins prove useful.
Packs are grouped by `PackIdentity` using UUID/version when available, or fallback name/location when metadata is incomplete. A representative pack is chosen for display, preferring top-level packs over embedded world copies, loaded metadata, icons, recent modified dates, and stable path ordering.
## Product Notes
World relationships resolve pack references to logical packs when possible. Unresolved references remain visible on the world detail side.
- “Search” solves retrieval.
- “Smart folders” solve recurring saved views.
- “Analysis” solves discovery and problem finding.
The displayed item list uses worlds, representative packs, skin packs, and templates. Embedded duplicate pack instances remain available through detail views.
These should stay distinct in the product even if they share the same underlying index.
## Persistence and Offline Cache
`SourcePersistenceStore` stores source cache data in SQLite under Application Support:
```text
Library/Application Support/World Manager for Minecraft/LibraryCache-v2026-05-28.sqlite
```
Persisted records include:
- source ID and folder URL
- source origin
- access descriptor
- availability
- bookmark data
- display name
- raw item payloads
- source snapshots
- last scan date
`SourcePersistenceCoordinator` restores sources at launch, applies cached images, repairs older records when needed, refreshes availability, then schedules reconcile scans when cached data may be stale.
This is what allows disconnected device-backed sources to display cached results.
## File Actions
File operations are currently focused on export, share, reveal/materialize, and directory preview:
- `ContentItemActionService` provides filenames, archive types, archive creation, and persistence of external representations.
- `ContentPackageExporter` stages content and creates ZIP-based Minecraft package archives through `/usr/bin/ditto`.
- Local source items can use native folders directly.
- Connected-device items are mirrored into temporary staging before export or reveal.
Archive extensions:
- worlds -> `.mcworld`
- behavior/resource/skin packs -> `.mcpack`
- world templates -> `.mctemplate`
## Current Product Capabilities
Implemented:
- Browse multiple local and connected-device sources.
- Restore cached sources at launch.
- Reconcile source changes.
- Search within the selected source/list projection.
- Sort by name, modified/last-played date, or size.
- Inspect world and pack metadata.
- Resolve world-to-pack relationships when metadata allows.
- Show embedded and backing pack instances.
- Export/share/reveal items.
- Preview package files with Quick Look.
Not implemented yet:
- Global cross-source search.
- User-created smart folders.
- Dedicated duplicate/integrity dashboard.
- Backup/restore workflows as first-class operations.
- Cross-source copy/move/import workflows.
## Future Intelligence Direction
The existing normalized index provides most of the data needed for richer library intelligence. Future work should build on `SourceContentIndexer`, persisted source caches, and projection requests rather than introducing a separate scanning path.
Useful next features:
- Global search across all visible and cached sources.
- Built-in smart folders for large worlds, recent worlds, unresolved pack references, duplicate packs, suspicious packs, and offline cached results.
- Duplicate analysis across sources by UUID/version, fallback identity, size, and modified date.
- Integrity checks for missing `level.dat`, malformed manifests, broken archives, and unresolved world pack references.
- Backup manifests that make exported backups browsable and restorable later.
Suggested implementation order:
1. Add a global read-only index projection over all `SourceLibrary.visibleSources`.
2. Add built-in smart folders backed by predicates over the normalized index.
3. Add cross-source duplicate and integrity analyzers.
4. Add explicit copy/backup/restore operations after analysis and conflict detection are reliable.
Keep search, smart folders, and analysis distinct in the UI even if they share the same underlying source/index data.

View File

@ -1,41 +1,126 @@
# Quick Look Plan
# Quick Look Architecture
## Current State
## Summary
Quick Look thumbnail and preview extension targets are present in the project and share the app's Bedrock package inspection layer:
The app includes Quick Look thumbnail and preview extensions for Minecraft Bedrock package files:
- `World Manager for Minecraft/Services/MinecraftPackageInspector.swift`
- extracts `.mcworld`, `.mcpack`, `.mctemplate`, and `.mcaddon`
- normalizes archives with either flat contents or a single nested top-level folder
- infers pack type for ambiguous `.mcpack` and `.mcaddon` archives
- `World Manager for Minecraft/Services/MinecraftContentMetadataReader.swift`
- shared manifest, icon, display-name, and world metadata parsing
- `World Manager for Minecraft/QuickLook/MinecraftPackageTypes.swift`
- central UTType identifiers and extension definitions
- `World Manager for Minecraft/QuickLook/MinecraftPackageQuickLookModel.swift`
- preview-friendly summary model
- `World Manager for Minecraft/QuickLook/MinecraftPackageThumbnailRenderer.swift`
- branded thumbnail rendering with icon fallback
- `.mcworld`
- `.mcpack`
- `.mctemplate`
- `.mcaddon`
Both extensions share the same package inspection and thumbnail rendering code used by the app target where possible.
## Targets
### Thumbnail Extension
`MinecraftPackageThumbnailExtension/ThumbnailProvider.swift`
- Implements `QLThumbnailProvider`.
- Calls `MinecraftPackageInspector.inspectArchive(at:)`.
- Renders a `CGImage` with `MinecraftPackageThumbnailRenderer`.
- Cleans up the temporary extraction directory with `MinecraftPackageInspector.cleanup`.
### Preview Extension
`MinecraftPackagePreviewExtension/PreviewViewController.swift`
- Implements `QLPreviewingController`.
- Inspects the selected package archive.
- Displays the package icon when one exists.
- Falls back to the generated thumbnail artwork.
- Keeps the inspection result alive while the preview is displayed, then removes temporary extraction files in `deinit`.
The preview is currently image-focused. `MinecraftPackageQuickLookModelBuilder` already builds structured facts, but the preview controller does not render those facts yet.
## Shared Package Inspection
`MinecraftPackageInspector` is the central archive reader for Quick Look:
- Accepts `.mcworld`, `.mcpack`, `.mctemplate`, and `.mcaddon`.
- Uses `ZipArchiveReader` to inspect ZIP entries.
- Supports packages with content at the archive root or under one top-level folder.
- Extracts only metadata-relevant files into a temporary inspection directory.
- Resolves content type from extension and manifest metadata.
- Reads display name, icon, world metadata, and manifest metadata.
Inspection results include:
- archive URL
- temporary extraction root
- resolved content root
- content type
- display name
- icon URL
- world metadata
- manifest metadata
Callers are responsible for cleanup.
## Metadata Readers
`MinecraftContentMetadataReader` provides shared metadata parsing:
- World display names from `levelname.txt`.
- Pack display names from `manifest.json`.
- World icons from `world_icon.*`.
- Pack icons from `pack_icon.*`.
- World metadata from `level.dat` through `BedrockLevelMetadataDecoder`.
- Manifest UUID, version, and minimum engine version.
- Pack type inference for ambiguous `.mcpack` and `.mcaddon` archives.
`MinecraftPackageQuickLookModelBuilder` converts inspection results into preview-friendly facts such as version, UUID, engine version, game mode, difficulty, last played date, seed, and Bedrock version.
## Thumbnail Rendering
`MinecraftPackageThumbnailRenderer` renders square thumbnail artwork:
- If the package has an icon, it draws that icon cropped to a rounded square with a subtle border.
- If no icon is present, it draws a generated voxel-style badge with content-type-specific colors.
- Rendering is done with AppKit bitmap drawing and returns a `CGImage`.
## Type Registration
The main app registers exported UTTypes and document roles for Minecraft package extensions in `World-Manager-for-Minecraft-Info.plist`.
The extension Info.plists list the same internal UTTypes under `QLSupportedContentTypes`:
- `us.b-wells.minecraft.mcworld`
- `us.b-wells.minecraft.mcpack`
- `us.b-wells.minecraft.mctemplate`
- `us.b-wells.minecraft.mcaddon`
## Relevant Files
- `World-Manager-for-Minecraft-Info.plist`
- `MinecraftPackageThumbnailExtension/Info.plist`
- `MinecraftPackageThumbnailExtension/ThumbnailProvider.swift`
- renders Quick Look thumbnails for supported Minecraft package files
- `MinecraftPackagePreviewExtension/Info.plist`
- `MinecraftPackagePreviewExtension/PreviewViewController.swift`
- renders a basic image preview from package icons or generated thumbnail art
- `World Manager for Minecraft/QuickLook/MinecraftPackageTypes.swift`
- `World Manager for Minecraft/QuickLook/MinecraftPackageQuickLookModel.swift`
- `World Manager for Minecraft/QuickLook/MinecraftPackageThumbnailRenderer.swift`
- `World Manager for Minecraft/Services/ArchiveInspection/MinecraftPackageInspector.swift`
- `World Manager for Minecraft/Services/ArchiveInspection/MinecraftContentMetadataReader.swift`
- `World Manager for Minecraft/Services/ArchiveInspection/ZipArchiveReader.swift`
Archive inspection is covered by tests in `World Manager for MinecraftTests/World_Manager_for_MinecraftTests.swift`.
## Current Limitations
## Remaining Work
- Preview rendering shows only an image, not the structured metadata facts.
- `.mcaddon` support resolves one content root; multi-pack add-ons are not yet presented as a compound package.
- The inspector extracts only metadata files, which is intentional for Quick Look speed but means package validation is shallow.
The target layer is intentionally thin, but the preview experience can still be improved:
## Verification
- render structured metadata with `MinecraftPackageQuickLookModelBuilder`
- include:
- package icon or branded artwork
- title
- package kind
- key facts like version, UUID, minimum engine, game mode, difficulty, and last played
- add explicit UI tests or fixture-driven render tests for package previews
Run:
## Verification Notes
```sh
xcodebuild \
-project "World Manager for Minecraft.xcodeproj" \
-scheme "World Manager for Minecraft" \
-configuration Debug \
build
```
- `xcodebuild ... build` succeeds.
- `xcodebuild ... test` should be run before release and whenever the shared archive inspection layer changes.
The unit tests cover archive inspection behavior in `World Manager for MinecraftTests/World_Manager_for_MinecraftTests.swift`.