Skip to content

Android port - #8

Merged
heisthecat31 merged 31 commits into
mainfrom
android-port
Sep 22, 2026
Merged

heisthecat31 merged 31 commits into
mainfrom
android-port

Conversation

@heisthecat31

Copy link
Copy Markdown
Member

EchoVR Cosmetics Editor — Quest Update

The Cosmetics Editor now runs on the Quest itself. Install the APK on your headset to edit cosmetics and repack them into Echo VR, with no PC needed. The Windows version gets the same fixes and improvements.

Downloads

File For
EchoVR_Cosmetics.apk Quest (sideload with SideQuest or adb install -r EchoVR_Cosmetics.apk)
EchoVR-Cosmetics-Editor.exe Windows (PC VR). Keep it next to the Settings folder, which holds ms_texconv.exe

Quest App (new)

  • Runs on the headset. Edit tints, emotes, banners, tags, emblems, decals, medals, pips, patterns, titles and emissives directly on your Quest.
  • Finds Echo VR by itself. On first launch the app asks for "All files access". Switch it on, come back, and the app locates the game's data.
  • Supports both install locations. Echo VR data is found under Android/media/com.readyatdawn.r15 and /sdcard/readyatdawn. If you have both, a repack mods both.
  • Repack only. No more extracting ~12k textures first. Previews are read straight from the game's files, and your changes are added as a new package chunk.
  • Proper Quest textures. Replaced textures are encoded to ASTC on the headset, matching the original's size, mipmaps, block size and colour space, so they load correctly in-game.
  • Both cosmetic databases are updated. Quest ships the cosmetic list twice (normal and "lowspec"), and both are now written, so edits apply on every headset.
  • Controller-friendly UI. Fixed the Quest pointer causing constant scrolling and turning clicks into drags.
  • PC-only features hidden in Quest mode. Chassis, bracers, boosters and fanfare audio are hidden there.

New Features

  • Install other mods. In Settings, pick a mod .zip made with other tools. Its files are added to your pending changes and applied on the next repack together with your own edits.
    • Mods made for the other platform are refused.
    • A mod's own cosmetic database is skipped, since the editor writes that itself.
    • Common zip layouts are supported.
  • Tint colour picker. Tints now have a colour picker next to each hex field. The hex fields only accept valid hex, so a typo can't break a colour.
  • Revert restores the original manifest and removes exactly the package chunks the editor added. This works on both PC (_3 onwards) and Quest (_1 onwards).

Fixes

  • Tint edits no longer reset when you click away. Changes are saved to disk immediately.
  • Generate Thumbnail for tints now uses the tint's real colours instead of solid grey, and the button only appears on the Tints tab.
  • No more freezes when selecting items. Texture previews load in the background.
  • Missing previews fixed for banners, tags, emblems, decals, medals, pips and patterns.

Changes

  • evrFileTools.exe and astcenc are now built into the app. The Settings folder only needs ms_texconv.exe (Windows).

heisthecat31 and others added 24 commits September 21, 2026 02:36
Derive every PC/Quest resource hash from its authored type name instead of
hardcoding them, so the two platforms cannot drift apart, and pin the results
against the values confirmed from the shipped binaries.

The PC and Quest builds name types with a Win10/Android suffix, and the cosmetic
database is additionally a different asset on each: r14_glb_global_root on PC
against r14_glb_global_root_lowspec on Quest.

Also decode the 256/248-byte texture header. evrFileTools models it as
width-at-+0x00, which reads 0xFFFFFFFF for every field; the real fields start at
+0xC0, and the header carries both the authored extent and the smaller resident
extent that actually ships. PC headers are 0x100 bytes and their inline payload
is a complete DDS file; Quest headers are 0xF8 and their payload is raw blocks.
Verified on real extracts: resident size matches mip-chain arithmetic for
6464/6464 Quest descriptors, and PC descriptors agree with their DDS headers.

Remove the Blender/Python mesh import from chassis, bracers and boosters along
with the embedded scripts, per the Android port's scope; the cosmetic metadata
editors for those categories are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Quest ships its textures as ASTC, which the editor had no way to read: the
existing path shelled out to astcenc.exe and brute-forced the block footprint
because nothing was reading the format out of the descriptor. This decodes ASTC
in process, and takes the footprint from the descriptor's format field.

Verified bit-exactly against ARM's astcenc across six footprints and two quality
levels, covering single and multi partition, dual plane, trit and quint
quantisation and seven endpoint modes. Then run over a real Quest extract: all
4,637 inline textures decode, in 3.2 seconds.

Two things worth recording, because both are silent when wrong:

The encoder scrambles weight values before encoding them, so the decoder needs
the combined unscramble-and-unquantise map rather than the plain quantisation
ladder. They agree for the pure-bit levels and differ for the trit and quint
ones, so using the wrong table decodes most blocks correctly and scrambles the
rest.

The payload is a descending mip chain, largest level first. Reading it the other
way round still produces an image, just the 1x1 tail mip.

A census of the extract found Echo uses only 4x4 and 8x8 footprints, only
single-partition blocks and only endpoint modes 6, 8, 10 and 12. The decoder
covers considerably more than that so an unusual texture still renders, but not
the HDR modes: those do not occur, and a guess at them would be worse than a
clear failure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A real Quest extract ships the cosmetic database under two asset names,
r14_glb_global_root and r14_glb_global_root_lowspec, and the two files are
byte-identical to each other and to PC's. Which one the runtime loads depends
on the device spec tier, so an edit written to only one applies on some headsets
and silently does nothing on others. Both are now written. This corrects an
earlier assumption that Quest used the lowspec name instead of the PC one.

Revert no longer deletes a hardcoded _3 chunk. PC ships _0.._2 so the first
repack appends _3, but Quest ships only _0 and appends _1, so the fixed name
missed the added chunk on Quest and left every chunk past _3 behind on a
twice-repacked PC. The stock chunk count is now recorded beside the manifest
backup while the install is still untouched, and revert removes everything above
it. Reading the count back out of the manifest is not an option: the manifest is
a zstd container, and its first word is the "ZSTD" magic rather than a count.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Previews went through ms_texconv.exe, which is Windows-only and reads DDS, so on
Quest it had nothing to work with: the payload is raw ASTC behind Echo's own
header, not a DDS file. Previews now use the in-process decoder and read the
extent and format out of the texture header rather than inferring them.

This also drops the temporary-DDS round trip: the old path wrote a .dds to the
Temp folder, ran texconv over it and deleted it, per texture. The PNG is now
written through a temp file and renamed, so an interrupted write cannot leave a
truncated preview in the cache.

Staged replacements are searched before extracted originals, so a texture that
has just been replaced previews as the replacement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The shipped Quest textures all come out of the same cooker, so they cannot show
whether the header model is right in ways only a hand-built file would expose.
This fixture is a replacement someone actually built for a Quest install: a
248-byte header whose declared resident size, mip-chain arithmetic and payload
length agree to the byte, decoding to a real 1024x1024 image.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Android will not let an app execute a binary it ships in its own data
directory, so shelling out to evrFileTools.exe could never work on the headset.
Its package code is pure Go with zstd as its only dependency, so the three
packages the editor needs are vendored under EvrFile and called directly. The
Windows-only Lone Echo extractor, which loads an Oodle DLL through syscall, is
not among them.

The extract filters are built from the platform layer rather than the
hardcoded type hashes the CLI carried, so they cannot drift from the folder
names the rest of the app uses.

Extraction is flat, as <output>/<type hash>/<asset hash>. The package's own
grouping would insert a numeric folder above the type hash, which is what the
CLI did, and FindExtractedAsset looks for the type folder directly under the
root — so a grouped extract leaves every asset invisible to the app. Pinned by
a test that extracts from a real install and then looks the database back up
the way the app does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The file and folder choosers drove a Windows.Forms dialog through PowerShell,
so on Android there was nothing to open. Fyne's own dialogs work everywhere the
app builds.

They are asynchronous, so the twelve call sites now pass a callback instead of
blocking on a returned path. Blocking would not have been an option anyway:
every one of these runs inside a widget handler, on the UI goroutine, which is
the same goroutine the dialog needs in order to answer.

A file chosen on Android arrives as a content:// URI with no filesystem path
behind it, so the chosen file is copied into the app's own storage and callers
are handed that copy, keeping the plain-path contract they already had. The
copy's name comes from the URI, which is user-controlled, so it is reduced to a
leaf name before being joined to the destination.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
On the headset the Quest data directory is detected at launch, at the same path
the texture editor pushes to:
/sdcard/Android/media/com.readyatdawn.r15/files/_data/5932408047/rad15/android.
If it is absent, the _data folders are scanned for another id with a rad15
install, so a differently numbered install is still found. A folder only counts
when it holds the package manifest. On Android the mode is forced to Quest and
the path is re-detected every launch rather than trusting a saved one.

Settings, staged assets and caches lived next to the executable, which has no
writable directory beside it on Android. The app is now created first and, on a
headset, its private storage root is used instead; desktop behaviour is
unchanged. The app also gets a stable ID, which Android needs for its storage
root.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FyneApp.toml gives the app its name, ID and icon for `fyne package`. The ID
matches the one the app is created with, which Android needs for its storage
root.

A custom AndroidManifest.xml replaces the generated one to add
MANAGE_EXTERNAL_STORAGE. Fyne's manifest only asks for the legacy storage
permissions, and on Android 11+ those do not reach another app's folder; the
game's data sits under Android/media/com.readyatdawn.r15. The user grants it
once, from the app's settings or with adb appops.

requestLegacyExternalStorage is deliberately absent: the packager's manifest
compiler rejects the attribute, and it only ever mattered on Android 10.

Builds with:
  ANDROID_NDK_HOME=<sdk>/ndk/30.0.16248370 fyne package -os android/arm64

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A full extract is several gigabytes, which a headset cannot spare, and the
editor never needed most of it. Extraction is gone: the Extract button, the
12.5 GB first-run prompt, the extract step in the repack dialog and the
extract code itself.

What the editor does need, it now gets without extracting:

- The cosmetic database is built in. In a real Quest install both of its asset
  names hold exactly the built-in bytes, so there is nothing to pull out.
- Texture previews, and the header of a texture being replaced, are read from
  the package one asset at a time. The manifest is parsed once and kept open,
  and each read decompresses only the frame the asset sits in. On a real Quest
  install this decodes 40 of 40 textures in 0.4 s including the manifest parse.
  The reader reopens when the manifest changes, as it does after a repack.

Staged replacements are still looked up first, so a replaced texture previews
as the replacement, and an existing extract folder is still used on desktop if
one is there.

The first-run prompt now only asks where the game data is. Picking any level
above it works (the game folder, _data, or the runtime folder), for either
platform. On a headset the data is detected, so the prompt becomes a note to
grant All files access if detection fails.

The in-process decoder handles Quest's ASTC but not PC's BC formats, which the
previous preview change had quietly broken on PC. The Windows build falls back
to texconv for those, fed from the package rather than an extract.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The cached package reader keeps the install's chunk files open between reads.
Repack deletes stale delta chunks and revert deletes the appended ones, and
Windows refuses to delete an open file, so both would have failed on desktop
whenever a texture had been previewed first. Both now close the reader first.

Adds an end-to-end repack test against a copy of a real Quest install (opt in
with EVR_QUEST_INSTALL; the source install is only copied, never written). It
edits a display name, stages the database under both Quest asset names,
repacks, and checks that the install gained exactly one chunk (_1), that both
names read back as the edited database, and that untouched textures still
decode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replacing a texture on Quest means encoding ASTC, which went through
astcenc-avx2.exe. Android will not run a binary an app ships in its data
directory, so the encoder is now compiled in: the astc-encoder 5.7.0 library
sources (Apache-2.0, LICENSE.txt alongside), a small C wrapper, and a cgo
binding that splits one image's work across up to eight threads the way
astcenc is designed to be driven.

It builds with NEON on arm64 (the Quest) and with SSE4.1 and POPCNT on amd64.
cgo refuses -msse4.1 and -mpopcnt for security reasons, so the desktop build
asks for them through -march=nehalem, which every x86-64 CPU since 2008 meets.
The two floating-point speed flags astcenc's CMake adds are also refused and
are left out; they only affect speed.

Encoding a test image and decoding it with the app's own decoder gives
40.9 dB PSNR at 4x4 and 36.7 dB at 8x8, the two footprints Echo ships.
Cross-compiles for android/arm64 with the NDK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replacing a texture on Quest encoded every image as a single 6x6 ASTC mip,
whatever the original was, glued a made-up 16-byte header onto it, and left the
texture header claiming the original's format (8x8 or 4x4) and mip count, so
the game read the blocks with the wrong footprint. Generated thumbnails also
wrote their Quest header to e2ef0854d0cd69b8, a typo for e2efe7289d5985b8, and
the fallback header was 256 bytes carrying PC's BC7 format code.

All of that now goes through one builder. It reads the original's header from
the game's package, resizes the picture to the resident extent, builds the full
mip chain largest first, and encodes every level with the built-in astcenc in
the original's own footprint and colour space (sRGB or linear). The header is
the original's with only the size field updated, and the texels go inline or in
the GPU file just as they did in the original. A texture with no original, such
as a new thumbnail, is built as the game's own thumbnails are: ASTC 4x4 sRGB,
one mip.

Checked against a real Quest install across every texture shape it has: 4x4
and 8x8, sRGB and linear, inline and separate payloads, 1 to 11 mips, and
extents that are not block multiples. Each rebuilt texture keeps the original's
header shape exactly, is sized to the byte, and decodes right way round.

Emote GIF import had a PC-only path (PC folders, BC7, PC header) and staged
files a Quest build cannot read. In Quest mode each frame now goes through the
same builder; frames beyond the emote's original count take frame 0's shape.

A texture that streams its largest mips keeps them: only the resident mips are
replaced, and the user is told that up close the game may still show the
original's detail.

The fanfare audio preview is Windows-only (PowerShell SoundPlayer on local wav
files), so it is not shown in Quest mode.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The repack test now also replaces two textures, one with its texels inline in
the header and one with a separate GPU payload, repacks them into the copy of
the install, and checks both read back out of the package as the replacement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Checked how RAD's cooker built the shipped Quest mips by rebuilding mip 1 from
mip 0 both ways and comparing with what shipped. For sRGB textures mip 1 is the
linear-light average in 1,431 of 1,492 decidable cases; for UNORM textures it
is the plain average of the stored values in 3,456 of 3,679. That is the
correct rule, and replacements did neither: they averaged gamma-encoded bytes
for everything, which darkens detail as it shrinks, and 1,145 of the 1,232
cosmetic textures are sRGB.

Replacements are now resized and mipped in the texture's own space: sRGB
colour in linear light, UNORM on its stored values. Colour is premultiplied by
alpha while it is filtered, so the colour of transparent texels cannot bleed
into opaque edges, and each mip is a 2x2 box average of the one above, as the
originals are. Rebuilding the shipped textures' mips 1-2 from their own mip 0
this way is closer to what shipped on 207 of 250 sRGB and 209 of 250 UNORM
textures, with mean squared error down 19% and 36%.

Also adds DecodeLevel, to decode any resident mip rather than only the first,
and drops the scratch go.mod files, whose folders have been removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fyne package increments it on every build, so installed versions stay ordered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
astcenc is C++, and the NDK links C++ against libc++_shared.so by default.
The APK does not ship that library, so the app crashed at launch with
"library libc++_shared.so not found". Linking libc++ statically into the
app library leaves only system libraries as dependencies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ask for "All files access" at startup. Echo VR's data belongs to the game, so
the editor needs it just to see the files; without it every read failed with
"open manifest: permission denied". Only the user can switch it on, so the app
checks Environment.isExternalStorageManager() through JNI and, if access is
missing, offers to open the system's per-app All files access screen, which
Horizon OS provides. Coming back to the app re-checks access and re-detects the
data directory, so granting it takes effect without a restart. If the screen
cannot be opened, the adb appops command is shown instead.

Hide the Chassis, Bracers and Boosters tabs (3D model data) and Fanfares
(audio) in Quest mode: the Quest build cannot edit either. The tab buttons now
fill a grid, four across on a headset rather than eight, so their labels no
longer overlap on a narrow panel.

Build the UI on Fyne's UI thread. On Android main() is not that thread, so
building widgets there made Fyne log a call-thread error for nearly every
widget and race the renderer, which showed up as the layout jumping and
scrolling on its own. The UI is now built from the app's OnStarted callback
and the window shown from there; call-thread errors on the Quest went from
dozens to zero. The fixed 1200x850 window size is skipped on mobile, where the
system sizes the window.

Also guard loadSettings, which wrote to the status bar before it existed, so a
malformed settings file would have crashed startup.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The UI scrolled on its own and turned clicks into drags on a Quest. Fyne's
Android layer turns every motion event that is not a press or release into a
touch move. A phone only sends those, but a Quest controller's pointer ray
sends a steady stream of HOVER_* events while merely pointing at the panel, and
the thumbsticks send SCROLL, all of which Fyne read as a finger dragging.
patches/fyne-v2.7.3/android.go drops hover and scroll events.

Go will not patch files in the module cache, so build_android.ps1 copies Fyne
into .build/ (git-ignored), applies the patch there, and points Fyne at the
copy for the length of the build, restoring go.mod and go.sum afterwards so
desktop builds are unaffected. It refuses to build if the Fyne version no longer
matches the patch, so an upgrade cannot silently drop the fix. Checked that the
APK's library is compiled from the patched copy.

Previews were blank in Banners, Decals, Emblems, Medals, Patterns, Pips and
Tags. Those editors looked for an already-cached PNG of their texture but never
asked for one to be made, which only worked while a full extract had filled the
cache. They now go through CachedTexturePath, which decodes the texture from
the package on demand.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Selecting a banner froze the app until its texture had been read from the
package, decoded and written out as a PNG; the first one of a session also paid
for parsing the package index, and an emote decoded every one of its frames
before showing anything. Previews are now decoded in the background. A cached
preview shows at once; otherwise the image is cleared, the texture decodes off
the UI thread, and the preview appears when it is ready, but only if the user
is still on that item, so a slow decode cannot overwrite a newer selection.
Concurrent requests for one texture share a single decode, emote frames fill in
as they arrive, and the package index is parsed in the background as soon as
the game data is found.

Generate Thumbnail showed on the Chassis, Bracers and Boosters tabs as well as
Tints. It recolours the tint template, so it is now Tints-only in both modes,
pinned by a UI test that clicks through every tab and selects an item.

Generated tint thumbnails came out plain grey. The button passed no colours, so
both regions were drawn white and then darkened. Measured against the game's
own tint thumbnails, the template's red region takes the colour in bytes 0-12
of the tint's data and the yellow region bytes 12-24 (76 of 77 tints), and the
game uses those colours exactly, so the 60% darkening the generator applied was
also wrong. With both fixed, thumbnails generated for the game's 91 tints match
the shipped ones at 28.7 dB mean PSNR, close to the ceiling set by the shipped
ones being ASTC-compressed.

Also moves the thumbnail generator's dialogs onto the UI thread; it showed them
from its background goroutine.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A tint colour typed on the headset kept snapping back. The editor saved on
every keystroke, but only a complete six-digit hex value can be stored, and the
Quest keyboard opens on letters, so what was typed ("EtghA1") was never valid
and was silently dropped; reselecting the tint showed the last stored value.

The hex fields now accept only hex digits (upper-cased, at most six) and show an
error until the value is complete. Each colour also gets a swatch and a Pick
button that opens a colour picker, so no typing is needed. Edits are written to
the tint the editor was opened for rather than whatever is selected when they
land, and are saved to disk immediately.

Regaining focus re-ran the Quest setup check, which rebuilt the open editor and
threw away half-typed text; on a headset that happens whenever the system
keyboard opens and closes. It now only refreshes the editor when the game data
has just been found.

Most other editors only change the database in memory and rely on Repack to
write it, and a headset can kill a backgrounded app while it sleeps. The app
now saves the database whenever it leaves the foreground, and never before the
database has loaded, which would save an empty list over the real one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Echo VR can live under Android/media/com.readyatdawn.r15 and under
/sdcard/readyatdawn on a headset. Both are now found, and a repack
backs up and mods each one; revert restores each one.

Tidy up: drop the model-editing Blender scripts and importer, and the
Settings/ tools and data the app no longer uses (evrFileTools and
astcenc are built in). Keep ms_texconv.exe, which PC mode still needs.
Ignore build outputs and the files the app writes when run from the
repo. Bring the README up to date.

The UI tests read widgets while background texture callbacks were still
running on other goroutines (the test driver runs fyne.Do inline), so
they failed intermittently. They now wait for the startup load and for
background texture work, which includes the emote frame loader.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ms_texconv.exe is Microsoft's DirectXTex texconv, redistributed under
MIT, so ship its licence alongside it.

The README now covers running on the Quest (file access, both data
locations, repack-only, the two database names), how textures are read
and rebuilt on each platform, the tint editor, building the APK, the
game-data test variables, and the project layout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Model import comes back for PC. Replace Model from .blend on the chassis,
bracers and boosters editors is restored, and shown in PC mode on the
desktop only. The Blender scripts are embedded in the Windows build only,
so the APK does not carry them. The file is used where it is on disk, so
a .blend keeps its relative texture paths. The editor no longer extracts
the game, so the base mesh is now read from the package when there is no
extracted copy; this finds 287 of the 289 model hashes in the shipped
cosmetics.

Install other mods (Settings) adds a mod zip made with other tools to the
staged files, so the next repack applies it with the editor's own edits.
Files are placed by their <type>/<asset> hashes, so the usual zip layouts
work. Mods for the other platform are refused and a mod's own cosmetic
database is skipped. Files are written through a temporary file outside
the staging folder, and zips over the size limits are refused.

Set the version to 8.1.0 in FyneApp.toml and AndroidManifest.xml. The
manifest is used as is, so build_android.ps1 now refuses to build when
the two disagree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread Cosmetics/boosters/boosters.go Fixed
Comment thread Cosmetics/boosters/boosters.go Fixed
Comment thread Cosmetics/bracers/bracers.go Fixed
Comment thread Cosmetics/bracers/bracers.go Fixed
Comment thread Cosmetics/chassis/chassis.go Fixed
Comment thread Data/platform.go Fixed
Comment thread Data/platform.go Fixed
Comment thread Data/platform.go Fixed
Comment thread EvrFile/manifest/scanner.go Fixed
Comment thread EvrFile/manifest/scanner.go Fixed
heisthecat31 and others added 5 commits September 22, 2026 17:04
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Comment thread EvrFile/manifest/scanner.go Fixed
heisthecat31 and others added 2 commits September 22, 2026 17:07
… between integer types'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…s during archive extraction ("Zip Slip")'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Comment thread Data/modinstall.go Dismissed
@heisthecat31
heisthecat31 merged commit b601b56 into main Sep 22, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants