release: v1.30.1 - #266
Merged
Merged
Conversation
…N warnings) (#253) formatOutcomeStatus collapses a 2+-warning ActionOutcome to a bare "Message (N warnings)" status suffix with no way to read the text — and on merged-pak games (Icarus) those merge-time warnings are the only report of cross-mod asset conflicts anywhere in the app. app.go's actionDoneMsg handler now auto-opens the existing info overlay (the update-results/fix-results machinery) listing every warning in full, at the same "> 1" threshold the collapse already uses: the overlay opens exactly when the text would otherwise be unrecoverable, and a single warning still renders inline with no modal. An update batch's ResultLines overlay keeps priority via the existing m.overlay == nil guard. The prototype deploy now returns two canned asset-conflict warnings so --prototype demo mode exercises the new path, mirroring prototypeAllSourcesWarning's rationale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…#253) Copilot PR #258 finding: a read-only overlay CAN be open when an action settles (promptOverlay deliberately doesn't gate on m.action.running - the Files overlay is the reachable case), and the plain m.overlay == nil guard silently dropped the warnings overlay there, re-losing the warning text. The warnings overlay now defers only to the update-results overlay the same handler just opened, and replaces any stale overlay otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eal pruned entries (#250) PruneUnclaimed conflated two causes of "unclaimed": stale/superseded content (#210's target) and a converted pak's deployable copy, which is unclaimed only because the merged pak claims its content (members=nil) while it remains the designated raw-fallback artifact. Any sibling-file ingest into the same version directory opened the prune gate and deleted the copy; a later conversion opt-out or merge failure then marked an empty member set and deployed nothing, silently, with the bytes still sitting in the retained source. Two-part fix, matching the issue's two directions: - Prevent: PruneUnclaimed exempts any unclaimed file whose content matches a retained source (size-then-MD5, the same content-identity attribution rawPakMembers uses in #241 - the one identity that survives the convert flip erasing the ingest-time manifest). - Heal: reconcilePakManifests' raw-fallback branch restores the deployable copy from the retained source when no cache member matches it, then claims and deploys it - entries already damaged by released versions converge instead of staying silently broken. Import-path fileIDs restore name-exact (the fileID IS the archive filename); download-path fileIDs get a deterministic <mod-id>_P.pak name, since the original URL-derived name is durably recorded nowhere. The sync-level heal test seeds the merged entry as present (the only realistic damaged state - a merge must have succeeded for the manifest to flip); an absent entry trips the pre-existing, unrelated #260. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot PR #258 suppressed finding: the comment claimed the overlay machinery is idle whenever an action resolves, which the same PR's stale read-only overlay fix disproved. Only the modal machinery is idle by construction; a Files overlay can be up, and the guard's refusal there is a deliberate tradeoff the comment now states. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
syncMergedPak's uninstall-to-zero branch and PurgeMergedPak hard-errored whenever the merged-pak cache entry was absent, because Installer.Uninstall started with cache.ListFiles, which fails on a missing version directory. Since the zero branch deletes that entry on its first successful pass, "zero merge sources + no merged entry" is the steady state after disabling the last merge source - every later mutation flow on that profile errored forever. Treat a missing cache entry as "nothing to undeploy" (ListFiles ENOENT -> empty), keeping the DB tracking cleanup and empty-dir sweep. This makes Uninstall honor the idempotency merged_pak.go's docs already claimed it had, and fixes PurgeMergedPak for free. Structural obstructions (e.g. a regular file blocking the cache path, ENOTDIR) still error. The two tests that used an absent cache entry as their deterministic undeploy-failure fixture now obstruct linker.Undeploy directly instead (a foreign regular file where the symlink linker expects its own link). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…entry Copilot review follow-up on #262: with the cache entry gone the deployment can still be fully on disk (copy/hardlink deploys own real files, not links into the cache). Skipping the undeploy loop while still deleting the deployed_files rows would orphan those files and erase the only record they were ours. Fall back to GetDeployedFilesForMod for the undeploy set instead; ownership rows upsert on overwrite, so the fallback never removes a path another mod has since claimed. The merged-pak steady state deleted its rows on the first zero pass, so the #260 shapes remain clean no-ops. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds the five pieces of Unreal/Icarus format knowledge core currently holds - base-pak location, pak fingerprinting, the .pak convert test, merge-source kind classification, and the merged artifact's name/label - as methods on *Icarus, with the kind constants moved into this package. Additive step: internal/source's MergeCompiler interface widens in the next commit, which swings internal/core over to these methods. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…am (#256) Closes all five format leaks the issue enumerates: 1. resolveBasePak (Icarus/Content/Data/data.pak path) -> mc.ResolveBaseArtifact 2. basePakIndexHash (go-unrealpak import in core) -> mc.FingerprintBase 3. isConvertEligiblePakFile's .pak suffix test -> mc.IsConvertibleArtifact (core keeps only the DeployCompile/ConvertPaks policy half) 4. MergeSourceExmodz/MergeSourcePak constants -> moved into the icarus package; core classifies via mc.ClassifyMergeSource and round-trips kinds as opaque strings 5. mergedPakFileName (zzz UE sort-order convention) and the 'Icarus Merged Pak' display name -> mc.MergedArtifactName/MergedArtifactLabel source.MergeCompiler widens from 2 to 8 methods and now states the full contract a second DeployCompile game must implement. Core resolves the compile source lazily on merge paths (only once something retained needs classifying), so no-compiler/no-retained flows keep succeeding exactly as before. ModHasPakMergeSource gains the *domain.Game parameter its classification now requires; callers in cmd/lmm, internal/tui, and moddetail updated. Test accommodations (no behavioral assertions changed): compile-source fakes gain an embedded fakeMergeFormat mirroring the icarus conventions; fixtures for DeployCompile games now map/register a MergeCompiler source (required by the seam where core previously classified statically); moved-symbol references (source.MergeSource* constants, mergedFingerprintsEqual's new classifier arg) updated in place. TestMergeSourceKind's table moved to icarus TestClassifyMergeSource. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…g-overlay fix(tui): auto-open a warnings overlay when an outcome collapses to (N warnings)
…prune-converted-pak # Conflicts: # CHANGELOG.md
…erted-pak fix(cache): keep a converted pak's raw-fallback copy through prune; heal pruned entries (#250)
…uninstall-absent-cache-entry # Conflicts: # CHANGELOG.md
…-256-mergecompiler-seam # Conflicts: # CHANGELOG.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…er seam (#256) Closes the sixth leak: core's static isExmodzFile hardcoded Icarus's NATIVE merge-source format, so a second DeployCompile game's native files would silently never reach the validate+retain branch - the exact core-edit-per-game outcome #256 exists to prevent. A new IsNativeMergeSource(fileName) method (the exact mirror of IsConvertibleArtifact) joins source.MergeCompiler rather than widening ClassifyMergeSource: ClassifyMergeSource must default UNKNOWN ids to the native kind (legacy fingerprint compat), so its result cannot distinguish 'genuinely native archive' from 'unknown junk' - using it for ingest routing would send every unrecognized file into validate+retain. All four call sites now go through the seam, via a new Service.isNativeMergeFile helper that prefers the file's own source's view and falls back to the game's sole compile source - keeping the 'native archive from a non-compile-capable source' download hard error reachable on mixed-source games. Two deliberate behavior deltas, both confined to games with NO resolvable compile source (broken config), where nothing is left to define 'native': - Importing a native archive into such a game still fails loud and still caches nothing, but with the legacy path's 'unsupported archive format: .exmodz' (the Extractor is extension-keyed) instead of the old compiler-specific message - that message required core itself to know the extension. TestImportMod_DeployCompile_NoCompilerSourceFailsLoud updated accordingly; pak/zip no-compiler imports are byte-identical. - A standalone core.NewImporter (nil resolver) now fails loud for EVERY DeployCompile import up front, preserving its original error verbatim; production only ever constructs the service-backed importer. The mixed-selection message loses its exmodz vocabulary: 'raw pak and native merge archive are alternate forms of the same mod - select one' (the 'alternate forms of the same mod' substring callers match on is unchanged). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lize the last format word (#256) - The MergeCompiler preamble now enumerates IsNativeMergeSource with the rest of the format vocabulary (its omission made the contract description incomplete for implementers). - The mixed-selection rejection drops 'pak': 'raw artifact and native merge archive are alternate forms of the same mod - select one' - the message was this PR's one remaining core string a second DeployCompile game would have had to edit. Declined (with reasoning on the PR): isNativeMergeFile deliberately treats an unresolvable compile source as 'nothing defines native' rather than propagating - an ambiguous-compilers config cannot stay hidden, as every merge-execution path (sync, import, staleness) still fails loud on the same resolution. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts (#256) Copilot round-3 catch, confirmed real: the legacy extract path content-sniffs zip magic (detectFormatFromPath's header fallback - NOT extension-only, as the round-2 design assumed), so letting a DeployCompile import fall through when the game's MergeCompiler cannot be resolved would silently extract and cache a real, zip-backed native archive without ValidateSource. Import path: an unresolvable compiler is now a hard error for EVERY import into a DeployCompile game - with no compiler, core cannot tell a native archive from anything else, and the resolver's own message names the fix. This restores TestImportMod_DeployCompile_NoCompilerSourceFailsLoud to its ORIGINAL assertions (the round-2 edit is reverted), and supersedes the import-side half of #221 I1: the pak fall-through test becomes TestImportMod_DeployCompile_PakNoCompilerSourceFailsLoud, doc'd with the history. The download-side I1 fall-through (per-source pin) is unchanged and its test passes untouched. Download path: unchanged - the non-compiler-source fall-through is a protected #221 contract. The residual (native archive from a non-compiler source on a game with NO resolvable compiler anywhere gets sniff-ingested) requires a hand-broken SourceIDs map plus a foreign source serving native archives; documented on isNativeMergeFile. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…isNativeMergeFile (#256) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…colliding files named in the rejection (#256) Item 1: #261's rawPakRestoreName held the last live format knowledge in core - a '.pak' extension test and the synthesized '<mod-id>_P.pak' Icarus override name. The extension test was already expressed by the seam (IsConvertibleArtifact: EqualFold-on-Ext and suffix-on-lowered are equivalent for every filename), so it reuses that; the synthesized name is genuinely new vocabulary and becomes the tenth method, RestoredArtifactName(modID) - the per-mod analogue of MergedArtifactName, byte-identical output ('<modID>_P.pak', core Base's the input) so healed installs keep their on-disk names. The import-vs-download provenance split STAYS in core: it follows from how ingest keys fileIDs, which is uniform across games - only the two format questions inside it moved. #261's heal/prune tests pass unmodified. Item 2: the mixed-selection rejection now names the actual colliding files ('Mod_P.pak and Mod.exmodz are alternate forms of the same mod - select one') - format-agnostic because the vocabulary comes from the selection itself, and strictly more useful than both prior wordings. The trigger is unchanged (booleans, not name-emptiness, so a file with an empty FileName still trips it). Variant-exclusivity expectations updated deliberately; cmd/lmm/install_test.go's local fake updated to mirror the production message shape it stands in for. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eration, stale doc name (#256) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e-agnostic (#256) Copilot round-6 triage: the nil guard is taken; the suggested DeployCompile short-circuit is NOT - it breaks a pinned CLI behavior: 'lmm mod convert' persists the per-mod flag on non-compile games with an advisory note (TestModConvertCommand_NonCompileGame), which requires classification to answer whenever the game's compile source resolves, exactly as the pre-#256 static test did. Documented on the method; the internal test now covers the non-compile-with-compiler true case and the nil-game case. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…compiler-seam refactor: push Unreal/pak knowledge behind the MergeCompiler seam (#256)
…absent-cache-entry fix: tolerate an absent cache entry in Installer.Uninstall (#260)
…ame the merged artifact (#255) On a DeployCompile game, per-mod success lines counted mods that individually deployed nothing, and the one artifact that actually reached the game directory - the profile-level merged pak built after the loop - was never named. Issue #255's decided option (b): - core: classify each mod BEFORE the deploy loop (enabledMergeSources) as merged / raw / individual, carried on DeployDeployed via the new DeployProgress.ModClass (DeployModClass enum); after a successful syncMergedPak, emit one new DeployMergeSynced event (participant count, artifact name via source.MergeCompiler.MergedArtifactName - no format literals in core, #256) and mirror the readout on DeployResult (MergedArtifact/MergedMods/RawFallbacks) for progress-less callers. - CLI: compile-mode header drops the misleading "using <method>"; per-mod lines label "(merged)" / "(raw)"; a post-sync footer prints "Merged N mod(s) -> <artifact>" (plus "(N deployed raw)" on conversion fallbacks) directly above "Deployed: N", which still counts merge participants. The one optimistic case - a pak labeled (merged) whose conversion then fails - is corrected by the existing conversion-failure warning plus the footer, per the issue's decided design. - TUI parity: coreProvider.DeployProfile appends the merge readout to the one-row Message from the new DeployResult fields (progress is nil there; warnings channel deliberately avoided - #253's overlay auto-opens on 2+). Non-compile deploy output is byte-identical; all pre-existing deploy tests pass untouched. New coverage: all three mod classes at core and CLI level, the conversion-failure correction path at both levels, non-compile gating, and the TUI message. Fixes #255 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t best-effort classify contract (#255) Both round-1 findings were doc-comment accuracy gaps, no behavior change: the CLI footer comment called Total the "merge-participant count" when it counts only mods the artifact actually carries (fallbacks ride RawFallbacks), and classifyCompileDeployMods claimed nil on "any resolution failure" while a mid-walk compiler failure deliberately returns the partial, best-effort map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… overlay (#259) Warnings emitted by successful updates in an apply-updates batch were folded into the aggregate Warnings slice, which the "update results" overlay never showed - and that overlay keeps priority over #253's warnings overlay, so the text was unreachable: the status line read "Applied 1 update(s) (2 warnings)" with no way to see them. On Icarus, an update that triggers a recompile emits merge-time asset-conflict warnings this way. applyUpdatesSequentially now appends success-emitted warnings to ResultLines as one trailing section (blank separator, then one line per distinct warning), deduped on exact text - they are profile-level merge diagnostics re-emitted verbatim by every update that re-runs the merge, so a batch would otherwise repeat the same text once per update. The aggregate Warnings slice is deduped identically so the one-row "(N warnings)" status count matches the section. Failure warnings are untouched: they already have their own ✗ lines in the same overlay, and including them in the section would render them twice. The overlay priority pinned by TestActionDoneResultLinesKeepPriorityOverWarningsOverlay is unchanged - the deferral is simply lossless now, because the winning overlay carries the warnings itself. prototypeProvider.ApplyUpdate now returns the same canned merge warnings prototype deploys already used (#253's demo-mode parity precedent, extracted into prototypeMergeWarnings), so --prototype exercises the new section and its dedupe. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ploy-output fix(deploy): label merged/raw mods and name the merged artifact in deploy output (#255)
…update-batch-warnings # Conflicts: # CHANGELOG.md
…ch-warnings fix(tui): render success-emitted batch-update warnings in the update-results overlay (#259)
Bump version, date the CHANGELOG section, add the comparison link, and regenerate man pages for the v1.30.1 release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Release PR for v1.30.1 (PATCH), bundling a fixes-only batch across cache pruning/healing, TUI warning visibility, compile-mode deploy readout correctness, and a refactor that moves Unreal/Icarus format knowledge behind the source.MergeCompiler seam, plus the usual release-version + man-page regeneration.
Changes:
- Fix cache prune + raw-fallback healing for converted paks so opt-out / merge-failure never silently deploys nothing (#250).
- Improve user-facing diagnostics in both CLI and TUI: compile-mode deploy output labels merged/raw mods and names the merged artifact (#255), and multi-warning outcomes are readable via overlay / results overlay sections (#253, #259).
- Refactor compile-format knowledge out of
internal/coreintointernal/source/icarusvia an expandedsource.MergeCompilercontract (#256) and makeInstaller.Uninstalltolerate absent cache entries (#260).
Reviewed changes
Copilot reviewed 104 out of 104 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| internal/tui/service_core.go | Uses game-aware ModHasPakMergeSource and adds compile-mode merged-artifact readout to deploy outcome message. |
| internal/tui/service_core_test.go | Updates compile-game fixture to register a merge compiler source for classification-dependent fields. |
| internal/tui/service_core_recompile_test.go | Embeds fakeMergeFormat into TUI recompile fake to satisfy widened MergeCompiler contract. |
| internal/tui/service_core_deploy_compile_test.go | Adds TUI parity test asserting deploy message names merged artifact without using warnings channel. |
| internal/tui/service_core_convert_test.go | Registers merge compiler source in convert fixture due to new classification path. |
| internal/tui/mutations.go | Appends success-emitted update warnings into ResultLines with exact-text dedupe (#259). |
| internal/tui/mutations_test.go | Adds regression coverage for update-batch warning visibility + dedupe, and updates prototype flow expectations. |
| internal/tui/merge_format_helpers_test.go | Adds TUI test-only fakeMergeFormat helper implementing format vocabulary methods. |
| internal/tui/app.go | Adjusts overlay-opening logic for result-lines overlay and auto-open warnings overlay behavior (#253). |
| internal/tui/actions.go | Documents that collapsed multi-warning status is recoverable via warnings overlay (#253). |
| internal/tui/actions_test.go | Adds end-to-end tests for warnings overlay opening/replacement and overlay priority (#253). |
| internal/tui/actions_provider.go | Adds prototype merge warnings for demo coverage (#253/#259) and documents ResultLines warning section semantics. |
| internal/tui/actions_provider_test.go | Adds tests ensuring prototype emits multi-warning outcomes for demo parity and adds per-ID ApplyUpdate outcomes for tests. |
| internal/storage/cache/cache.go | Implements prune exemption based on retained-source content identity (size+MD5) (#250). |
| internal/storage/cache/cache_test.go | Adds unit test proving prune keeps suppressed raw-fallback copy when it matches retained source (#250). |
| internal/source/source.go | Widens and documents MergeCompiler as the complete compile-mode game contract (#256). |
| internal/source/icarus/merge.go | Switches pak-kind checks to Icarus-local kind constants after moving kind vocabulary. |
| internal/source/icarus/merge_test.go | Updates merge tests to use Icarus-local kind constants. |
| internal/source/icarus/icarus.go | Updates comment to reference IsNativeMergeSource after seam move. |
| internal/source/icarus/format.go | New: Icarus implementation of MergeCompiler format-vocabulary methods (base artifact, fingerprinting, kinds, names). |
| internal/source/icarus/format_test.go | New: unit tests for Icarus format-vocabulary seam methods (#256). |
| internal/core/service.go | Removes UnrealPak dependency; routes native/convertible checks via MergeCompiler; improves mixed-variant error to name colliding files (#256). |
| internal/core/service_test.go | Adds repro test ensuring sibling re-ingest does not prune converted pak raw-fallback copy (#250). |
| internal/core/service_import_compile_test.go | Updates import behavior tests to reflect compiler-required classification for all DeployCompile imports (#256). |
| internal/core/service_icarus_compile_test.go | Embeds format helper into core fake compiler source to satisfy widened interface (#256). |
| internal/core/pak_convert_e2e_test.go | Updates assertions to treat kind strings as opaque values (“pak”/“exmodz”) instead of shared constants. |
| internal/core/moddetail.go | Makes ModHasPakMergeSource game-aware at callsite. |
| internal/core/moddetail_test.go | Registers compiler source in DeployCompile subtests due to classification now resolving via compiler (#256). |
| internal/core/merged_pak_test.go | Adds/extends tests for #260 absent-entry behavior and #250 raw-fallback healing; adjusts fixtures for compiler-based classification. |
| internal/core/merged_pak_internal_test.go | Updates helper tests to provide classifier + adds minimal compiler source for ModHasPakMergeSource tests. |
| internal/core/merged_pak_import_flow_test.go | Embeds format helper in import-flow compiler source fakes (#256). |
| internal/core/merge_format_helpers_test.go | New: core_test helper implementing format vocabulary for MergeCompiler fakes (#256). |
| internal/core/installer.go | Makes uninstall idempotent on absent cache entry, falling back to DB-tracked deployed paths (#260). |
| internal/core/installer_test.go | Adds tests for absent-entry uninstall semantics + DB fallback removal behavior (#260). |
| internal/core/importer.go | Resolves compiler up front for DeployCompile imports to determine native/convertible formats safely (#256). |
| internal/core/flows.go | Adds compile-mode deploy progress fields/events and deploy result merge readout fields (#255). |
| internal/core/flows_variant_exclusivity_test.go | Updates expected mixed-variant error text to include colliding filenames (#256). |
| internal/core/flows_test.go | Updates uninstall failure fixture now that absent cache entry is no longer an error (#260). |
| internal/core/flows_deploy_compile_readout_test.go | New: core tests for compile deploy mod classification + merge footer event/result fields (#255). |
| docs/man/man1/lmm.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-verify.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-update.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-update-rollback.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-uninstall.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-tui.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-status.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-source.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-source-validate.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-source-list.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-search.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-purge.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-sync.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-switch.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-reorder.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-list.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-import.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-export.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-delete.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-create.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-profile-apply.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-unlock.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-show.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-set-update.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-lock.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-files.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-enable.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-edit.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-disable.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-mod-convert.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-list.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-install.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-import.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-show-default.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-set-default.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-list.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-detect.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-clear-default.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-game-add.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-deploy.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-conflicts.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-completion.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-completion-zsh.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-completion-powershell.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-completion-fish.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-completion-bash.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-auth.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-auth-status.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-auth-logout.1 | Regenerated man page version header for v1.30.1. |
| docs/man/man1/lmm-auth-login.1 | Regenerated man page version header for v1.30.1. |
| cmd/lmm/uninstall_test.go | Updates CLI uninstall failure fixture consistent with absent-cache-entry uninstall semantics (#260). |
| cmd/lmm/root.go | Bumps CLI version constant to 1.30.1. |
| cmd/lmm/mod.go | Updates mod-convert gating to use game-aware pak-source detection (#256). |
| cmd/lmm/mod_convert_test.go | Registers compiler-capable source wrapper in convert tests due to compiler-based classification (#256). |
| cmd/lmm/merge_format_helpers_test.go | Adds CLI test helper implementing widened MergeCompiler format vocabulary methods. |
| cmd/lmm/list.go | Updates list output’s ConvertPaks field gating to use game-aware pak-source detection. |
| cmd/lmm/install_test.go | Updates mixed-variant validation helper + expected error string to include colliding filenames (#256). |
| cmd/lmm/install_compile_test.go | Embeds format helper into compile install fake source to satisfy widened interface (#256). |
| cmd/lmm/deploy.go | Adds compile-mode deploy header/labels and merge footer printing based on new progress event fields (#255). |
| cmd/lmm/deploy_compile_test.go | New: CLI compile deploy tests covering labels, footer, conversion-failure correction, and non-compile gating (#255). |
| CHANGELOG.md | Finalizes 1.30.1 release notes and updates comparison links. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v1.30.1 — a fixes-only batch. PATCH per the versioning rules: no new commands, flags, or capabilities; five bug fixes plus one internal refactor.
Contents
(N warnings). On merged-pak games those warnings are the only report of cross-mod asset conflicts anywhere in the app.(merged)/(raw)/plain and names the artifact.internal/corebehindsource.MergeCompiler. No user-visible change except a better mixed-selection error.DeployCompileprofile with zero merge sources failed every subsequent sync/deploy/purge with a loudno such file or directory. Uninstall of an absent cache entry is now a no-op removal.Prep commit
Single commit
163c69a: version bump incmd/lmm/root.go,[Unreleased]moved to a dated[1.30.1]section, comparison link added,make manregenerated (the genman test enforces this — verified passing).Verification
go build ./... && go vet ./...clean,gofmt -l ./cmd ./internalempty,go test ./...exits 0 across all packages, genman test green. Every constituent PR was independently verified and merged green, and #253/#255/#259 each passed a manual TUI smoke test before merge.Notes
#256 was the largest change — it widened
MergeCompilerfrom 2 to 10 methods so a secondDeployCompilegame becomes a new source package plus one registration line. Two format leaks were caught during review that the original issue had not enumerated (isExmodzFile, and.paknaming reintroduced mid-flight by #261), both closed before merge.🤖 Generated with Claude Code