Files
nxnative-easy/docs/frontend-library.md
T

218 lines
13 KiB
Markdown

# Personal library and structured build activity
## Reviewed references
The owner requested a library inspired by the organization of
[NX2Apple](https://github.com/LNPANDY/NX2Apple/tree/0313148688ec6e7954e4d299d26a9a91d19fe7dc)
and the upstream [frontend contract](https://github.com/seedds/nxnative/blob/ceaf6d6ee21bdfb986e9b6f97cbb1a7ce539991d/docs/frontends.md).
The review covered NX2Apple's Swift library/launcher, progress model, screenshot
and MIT license. The library, navigation and timeline here are our own SwiftUI
implementation: no source, fonts, artwork, layout or visual assets were copied
from that frontend. Cards reuse this fork's existing catalog artwork.
These are reviewed reference revisions, not new integrated engine revisions.
No upstream runtime merge or unsupported game announcement is implied.
The useful separation is a persistent collection, a preparation workspace and
activity visible while browsing. Upstream's JSON stream, not human log wording,
is the interface for stages/counts/ETA. A Mac game is opened as its built app;
its own launcher remains responsible for supported settings and stored choices.
We do not set DM_LAUNCHER=0, synthesize settings for missing launcher metadata or
write another preference store. Game-runtime text logs remain diagnostics rather
than an API for live game/controller state.
## Player flow
1. **Add game** selects one existing game folder. The same preparation form asks
for Mac or iPhone/iPad and the user's own keys. This is not a downloader.
2. The personal library remembers folders across launches, including the previous
game folder from an older launcher. It only links paths and small metadata;
it never moves game inputs, build caches, keys or saves.
3. Each entry resolves its title/art from the local accepted profile catalog when
possible and shows the outputs actually found: complete Mac app, iOS IPA or
unprepared/unavailable folder. A prepared IPA means ready for installation,
not proof that the game is installed or plays on a phone.
4. Selecting a game shows its artwork, actual platform outputs and actions.
**Play on Mac** opens its existing Mac app. **Install on iPhone / iPad** opens
our native installer for an existing iOS output. When both outputs exist, both
actions remain visible. **Prepare or update** returns to the common form and preserves
existing preparation identities. Native authentication/install validation
limits in [sideloading](sideloading.md) still apply.
5. Browsing and searching remain available while a build runs; switching the
active folder, rebuilding, removing entries, signing or updating the launcher
waits for the current operation. There is one active build, not a hidden queue.
6. **Remove from library** removes only the shortcut after confirmation. Source
folders, outputs, save data and caches remain. Unavailable external drives or
deleted outputs stay listed honestly; refreshing/reopening rechecks readiness.
The compatibility catalog is a separate action. An accepted game profile does
not automatically appear as an owned game, and the library supplies no game files.
## Devices navigation
Since 1.10.1, Devices is a page beside Library and Prepare, never a navigation
modal. Its game list uses local preparation IDs and exact installation records;
it does not show other user apps. Legacy discovery uses only the minimal ID
index before querying matched game metadata, as described in
[restricted discovery](sideloading.md#inline-devices-and-restricted-game-discovery-1101).
## Persistence
`~/Library/Application Support/nxnative Easy/library.json` is a schema-1 private
index of item IDs, canonical folder paths and dates. No game bytes, encryption
keys, Apple credentials or cloud-save packages are stored there. Writes are
atomic with a private directory and 0600 file. Symlink aliases deduplicate to
one folder. Invalid/unsupported metadata is preserved and disables overwriting
that index; the app does not silently replace it with an empty library.
Output discovery reads our per-folder `nxnative-mac.json`/`nxnative-ios.json`,
bounded metadata and Mac bundle identity/host/embedded-data presence. It does not recursively
scan drives or open packages from unrelated folders. Both platform outputs can
coexist; a missing output is no longer offered as ready. The library adds no
new game settings or cloud synchronization.
## Build activity
The dock stays visible on the library and preparation pages with the current
game/platform, stage, counters, current-stage fraction and callback ETA. A fraction
is explicitly for the current stage, not a fabricated overall percentage. Unknown
work is indeterminate. Finished/cancelled/failed results stay reachable through
**View activity** until a new build begins.
The preparation timeline uses `stage`, `step`, `progress` and `stage_end` events;
`n` may grow and a new step resets counters/ETA. Only reported completions are
marked done while running. Process exit/cancellation closes the remaining active
stages appropriately. Non-finite/out-of-range fractions and unsafe ETA values are
ignored. Retained log-tail replay merges the known timeline, rather than forgetting
earlier stages. The existing worker still captures stderr, forwards cancellation
to the whole process group and preserves original compiler logs. No new inferred
runtime events or game-log text parsing were added.
## Validation boundary
Foundation fixtures cover private index persistence, folder alias deduplication,
both platform outputs, missing output/folder handling, metadata-only removal and
malformed-index preservation. Structured progress fixtures cover growing totals,
actual ETA, resets, retained history, invalid values and failed/cancelled exit.
Offscreen visual checks use synthetic folder/output metadata and existing artwork;
they do not build, install or play a game. Production compilation/signature checks
validate the launcher bundle, not Apple login or game/device compatibility.
## Collection detail and application account (1.12.0)
The library uses a searchable game list and selected-game detail: large existing
artwork, platform readiness and play/install/update actions. Search selection
falls back to the first matching result; unavailable folders remain listed.
An iOS output is described as prepared, not as installed or tested on a phone.
No input paths or save locations migrate in this presentation change.
Apple Account is an application-level destination in the persistent sidebar,
reachable from Library, Prepare and Devices. It shows the authenticated email
or an explicit signed-out state. The account page is inline and contains no
device picker or installation action. Device installation still uses the shared
session and retains each app's account/team/device identity. Devices contains
no account card and explicitly explains that save export and RomFS copy require
connection/trust, not Apple sign-in. Account changes are disabled while the
helper is busy. This does not change login persistence or sign-in validation.
See the [expanded NX2Apple review](nx2apple-review.md) for the pinned source
inventory, useful features, integration decisions and validation limits.
## Guided preparation and verified device state (1.13.0)
**Add game** starts with platform selection, then one source folder, external keys,
review and compilation. Previous outputs can be used explicitly from review;
starting a new game clears only the form selection, not collection entries or
files. A drop anywhere in the workspace enters this flow. Package files must
share one parent folder; a `prod.keys` drop selects only its external parent.
The same source-folder validator rejects repository paths and symlink aliases.
No dropped file is copied or rewritten. Multiple-source-folder ambiguity is an
error, and preparation/signing never begins on a drop.
For iOS, the resulting IPA is passed to the installer directly: select the paired
device, use the global Apple account if needed, choose its team, review the
existing app identity and confirm installation. Reading the team's registered
devices is separate from physical connection. The response does not expose a
guaranteed remaining-slot count. Since 1.14, explicitly identified free memberships
show a labelled estimate from the reviewed policy and distinct returned records;
unknown membership never inherits an assumed free-account quota. Signing/install execution remains subject
to the existing validation limits in sideloading.md.
The library separates a prepared local IPA from an observed device installation.
Scoped discovery records only matched own-game identifiers, device names, version
and check time in private `device-games.json` beside the app's refresh index.
Connected/verified observations and cached last-seen observations have different
labels. Disconnecting or reopening the app cannot turn a historical observation
into current proof. A successful scoped rescan removes observations for games no
longer returned within that scope; an error does not erase the last good record.
No unrestricted app inventory, account login or game-container read is needed.
A read-only physical check found the existing Metroid installation and wrote
only this private local metadata; it did not install or modify anything.
## Rebuild advice, diagnostics and completion notices
Successful desktop preparations record the source commit per platform in optional
fields in our private collection index. Existing per-folder source revisions are
read as a fallback. The checker compares relevant runtime/build inputs and the
selected game's own profile with the recorded commit, including tracked working
changes. Documentation, tests and frontend-only changes do not alone recommend
rebuilding. A missing/malformed/unavailable commit is **unknown**, not proof that
a build is current. Advice is informational; it never rebuilds a game by itself,
changes installed apps or migrates a save. It compares source history, not the
installed binary's contents, and a dirty build is not a reproducible snapshot.
**Copy diagnostics** is available under Settings → General and in build logs.
It copies app/OS/source/target/stage and up to 50 build-log lines. Home prefixes,
key-value material, email and authentication/device-detail lines are redacted.
Raw signing/provider logs, credentials and environment dumps are not included.
Original compiler logs remain available separately and are not rewritten.
Completion notifications default on, with macOS permission requested at the first
real build. The account page offers an off switch. Success and failure notify
only while the app is in the background; cancellation is silent. A notification
click activates the app and requests Library or build activity. System permission
and notification delivery policies still apply. Unit/offscreen runs do not ask
for notification permission.
Compilation shows structured stages, real counters, current-stage percentage,
elapsed time, live logs and source-provided ETA when available. No overall ETA is
invented. A stage or installation operation without a percentage/estimate says so
and retains elapsed-time/log visibility. The preparation step rail represents
workflow milestones, not the compiler's overall percentage.
## Global settings and controller testing (1.14.1)
The sidebar footer now contains one Settings destination. Account email, language
and version no longer compete in its narrow column. Settings has three sections:
General (language, completion notices, redacted diagnostics and version), Apple
Account (the same shared session/team/registration UI) and Controller (the live
input tester). The standard Command-comma shortcut opens this in-window page.
The tester is embedded and scrollable, without a Close button or navigation
modal. It detects attached controllers and displays buttons, sticks and triggers
without choosing a platform, game or source folder. It samples only while visible
and clears transient input on leaving; no pairing, input-handler installation or
game/file/preference modification was added. The preparation screen no longer
contains controller status or a test action. Controller gameplay mappings and the
four in-game touch profiles remain unchanged.
![Settings, Spanish interface example](images/nxnative-settings-es-v1.14.1.png)
![Controller test embedded in Settings](images/nxnative-controller-settings-es-v1.14.1.png)
Screenshots use the actual SwiftUI views and synthetic library records; no real
account, game launch or physical controller result is represented.
## In-window compatibility (1.14.2)
Compatibility is a workspace page with an active sidebar item, flexible layout,
search, live profile counts, artwork, versions and existing game-note links.
All open-catalog intents, including preparation's View all and the empty-library
action, route to this page. The catalog has no sheet, Close button or fixed modal
size. The shared preparation model, active build and logs remain alive while
browsing. Catalog membership remains separate from owned/installed games.
![Compatibility as an in-window page](images/nxnative-compatibility-en-v1.14.2.png)
Native offscreen capture using the repository catalog; these are support
profiles, not an owned collection or supplied game files.