Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ jobs:
test:
runs-on: windows-latest
timeout-minutes: 20
env:
SCOUT_RETAIN_FIXTURES: "1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
Expand Down
19 changes: 19 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Model Scout

Start with [HANDOFF.md](HANDOFF.md), then read only the linked guidance relevant
to the task. Inspect Git status and recent commits before editing. Preserve WIP.

Keep personal libraries and live app profiles untouched during development.
Use generated fixtures and isolated `SCOUT_TEST_DATA` profiles. Cloud calls
require explicit opt-in. Archive contents are opt-in for each scan. Transfers
must be reviewed, exclusive and verified; never overwrite originals or targets.

Never delete files, directories, branches, worktrees or user records without the
owner's explicit approval. Set `SCOUT_RETAIN_FIXTURES=1` for development/CI checks
unless fixture deletion has been authorized. This mode omits destructive fixture
checks; it does not establish source-removal or collection-removal UI coverage.
Keep generated artifacts. Do not reset, clean, stash or broadly stage work.

Maintain the canonical handoff with scope, changed paths, checks, limitations and
next steps. Keep private catalogs, source paths and logs out of Git. Use explicit
file paths for commits. Match documentation claims to fresh evidence.
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

## 0.5.2

- Add game-library scanning of all regular file types, including editor sources,
unknown extensions, documentation and extensionless files; retain model mode.
- Add file-family and extensionless filters, saved family filters, local raster
previews and a unique-results view that respects current filters.
- Prepare reviewed unique-file libraries with fresh SHA-256 hashes, a new
category/family organization, duplicate aliases, historical original paths,
collection provenance, category JSONL indexes and a Markdown entry point.
- Copy unique assets with source/hash checks, exclusive targets, verification,
cancellation and copy journals; keep every original source file.
- Flag maps, atlases and other reference-bearing files for review before game
use. Reference rewriting and source/editor conversion are not included.
- Batch hash persistence and bound index writers for large libraries. Retain
generated build outputs instead of clearing the output directory on each build.
- Split category indexes into 1,000-entry chunks and place unique assets in
hash-prefix subfolders to keep large collections navigable. Sanitize Windows
reserved folder names and package only current manifest outputs.
- Retain duplicate aliases when preparing from the unique-results view, reject
destinations inside any scanned root, and restore catalog mode and roots after
cancelled or interrupted scans.

## 0.4.1

- Search filenames by default, with explicit path and all-details scopes retained in saved searches, selection, and CSV exports.
Expand Down
83 changes: 83 additions & 0 deletions HANDOFF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Model Scout current handoff

## 2026-10-03 — Game asset library

Goal: extend the existing discovery, filtering, duplicate and copy workflows to
support a complete game-asset directory. The owner will choose the destination
and run the feature in the updated application. Development must not copy,
move or delete personal assets or use the live app profile.

Approved design: game mode indexes all file extensions and extensionless files;
archive contents remain opt-in. Prepare a new unique-file library with fresh
SHA-256 hashes, category/family folders, readable names, source aliases,
historical original-path mappings when available, category JSONL indexes and a
Markdown entry point. Copying requires a separate reviewed action. Preserve
originals and never overwrite targets. Flag relative-reference files; do not
claim that maps/atlases/projects are repaired or ready for runtime use.

Branch: `codex/game-asset-library`, based on merged PR #2 / main `92789a0`.
Implementation is complete in `app/game-formats.cjs`, `app/game-library.cjs`, the
scanner, catalog, IPC/preload, asset-library dialog, raster previews and tests.
New asset folders use category/family/hash-prefix paths and readable hashed names;
category JSONL indexes have at most 1,000 entries per chunk. Hash updates are
batched and index writers are bounded. Packaging retains earlier frontend/output
files and selects only current manifest outputs.

Initial evidence: game discovery and verified unique-copy tests pass. A separate
read-only inventory counted 201,335 files, 609 directories and 60 extensions;
fresh content hashing found 160,096 unique hashes and 41,239 extra copies, with
no read errors, source fingerprint changes or historical hash mismatches.
These private library facts are validation evidence, not distributable content.

Verification: 31 core/feature tests pass with `SCOUT_RETAIN_FIXTURES=1`; all eight
source and all eight 0.5.2 packaged desktop workflows pass. Format/build,
dependency audit, unsigned Windows packaging and full source/notices ZIP pass.
ZIP SHA-256: `e32f88e4951f7cd4fb4d71729662074fff1fc56d640040aaa3c6f41e8d6afde0`.
Artifact: `release/0.5.2/Model-Scout-0.5.2-Windows-x64.zip`. ASAR verification
matched six core source files and all six manifest frontend outputs; the ZIP
contains 20 entries including four pinned importer/source archives and notices.
The real game-mode scan took 25.09 seconds with zero errors and an average
unfiltered gallery query of 19.42 ms. Private receipt:
`artifacts/benchmarks/1791080840283/receipt.json` (never publish its source paths).

A negative anchored test-name exclusion unexpectedly ran the earlier full
31-test suite, including generated fixture removals, and all passed. This was
reported to the owner; only isolated fixtures were affected. A harmless probe
verified positive skip-pattern behavior. Retained-fixture checks now omit four
core move/relocation tests and desktop source/collection removal. The owner has
not answered the deletion exception question; do not run those remaining
destructive desktop workflows without approval. CI uses retained-fixture mode.

Delivery: [PR #3](https://github.com/the3dcoder/ModelScout/pull/3) is open and
attached to the app task. Check its live Windows checks for hosted verification;
the local checks below cover the actual source and packaged build. After review,
the owner can extract the complete ZIP, select Game asset library, scan, choose
Create asset library, prepare, then confirm the reviewed copy. Do not run that
copy on their behalf. Keep local candidates/artifacts. The unique library is a
snapshot at preparation time; it does not continuously synchronize source files.

Review checkpoint: three P2 findings reproduced with failing tests, then fixed:
unique-view preparation now expands only the display collapse to retain aliases;
destinations are checked against all scanned roots including empty/unmatched ones;
cancelled and interrupted scans restore previous mode/root metadata with attempted
scope retained separately. The 31 retained core tests pass after these fixes.
Read-only follow-up review found no remaining Important/Critical findings.
Final 0.5.2 checks passed: `SCOUT_RETAIN_FIXTURES=1 npm test` (31), build,
`npm run test:app` (eight), `npm run format:check`, `npm audit --omit=dev` (zero),
`npm run package`, retained `npm run test:packaged` (eight), and
`npm run release:bundle`. The unsigned ZIP hash and packaged source/manifest
bytes were independently checked. Preserve earlier local 0.5.0/0.5.1 candidates.

Hosted checkpoint: paired runs on both initial heads disagree on the cancelled
mode UI check: one passes while one times out waiting for the family selector.
Core/build checks pass. Ten additional local game workflows and a renderer run
at 6x CPU throttling pass. Progress/metadata failure diagnostics were added;
the diagnostic head `c2d0db6` passed both hosted Windows runs
[37173760635](https://github.com/the3dcoder/ModelScout/actions/runs/37173760635)
and [37173762458](https://github.com/the3dcoder/ModelScout/actions/runs/37173762458).
Read-only tracing found no confirmed production race. Keep the diagnostics and
investigate if the earlier intermittent timeout recurs; do not claim its cause
was fixed. No production code changed after the verified 0.5.2 bundle.

See [README](README.md), [verification](docs/VERIFICATION.md) and
[roadmap](docs/ROADMAP.md) for current product behavior and evidence boundaries.
72 changes: 69 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Model Scout

A local Windows workbench for finding, previewing, and organizing 3D models and printing files.
A local Windows workbench for finding, previewing, and organizing 3D models, printing files, and game asset libraries.

Search folders or drives, browse a cached gallery, keep multi-part projects together, and review exactly what will be copied or moved. Model Scout also includes filament and resin cost profiles and basic STL inspection and editing.

## Run it

Use Windows 10/11 x64. Build the release ZIP with the commands below, or download a published build when one is available under [Releases](https://github.com/the3dcoder/ModelScout/releases). Extract the complete ZIP and run **Model-Scout-0.4.1.exe**. No installer is required. The current build is unsigned.
Use Windows 10/11 x64. Build the release ZIP with the commands below, or download a published build when one is available under [Releases](https://github.com/the3dcoder/ModelScout/releases). Extract the complete ZIP and run **Model-Scout-0.5.2.exe**. No installer is required. The current build is unsigned.

The portable executable stores its catalog, thumbnails, profiles, and transfer logs in `%APPDATA%\Model Scout`. Back up that folder while the app is closed if you want to preserve your library metadata. Source models stay in their original folders until you confirm a move.

Expand All @@ -17,7 +17,60 @@ npm ci
npm start
```

## Organize a library
## Create a unique game asset library

1. Select **Game asset library · all files**, add folders, then **Search locations**.
This mode retains every regular file, including unknown extensions and
extensionless license files. Links/junctions are skipped. Archive contents
remain opt-in; the archive containers themselves are indexed.
2. Browse by family, extension, suggested category, tags or filename. Common
raster images up to 8 MiB have local on-demand previews; 3D thumbnails retain
their existing cache. SVG/editor formats and unsupported media remain listed.
3. Choose **Create asset library** and select the entire scan or current filters.
Choose an existing parent outside the scanned folders. Preparation creates a
new timestamped folder, hashes each selected file, and writes a reviewable
catalog and full copy plan. A failed or cancelled catalog cannot be copied.
4. Review the unique count, size, sample organization, full copy plan and reference
warnings. Confirm the review checkbox, then **Copy unique assets to new library**.
Copies use new category/family/hash-prefix folders and shortened readable names with full
SHA-256 suffixes. Identical category/family levels are combined. Exactly one
copy is planned per SHA-256; every original remains in place. Targets are never
overwritten, source fingerprints/hashes are rechecked, and copies are verified.
5. Give another chat the new folder's **START_HERE.md** path. It links to smaller
category indexes, split into at most 1,000 entries each. `assets.jsonl` contains one canonical asset per hash;
`sources.jsonl` retains every source/duplicate alias, pack mapping, tags and
collection provenance. `copy-plan.jsonl` records full destinations;
`copy-receipt.json` and `copy-journal.jsonl` establish which copies succeeded.

The **Unique files** view collapses hash-confirmed duplicates within the active
filters. Unhashed files stay visible. Run **Check duplicates** or prepare an asset
library to establish hashes; a filename match alone never removes a result.
Preparing from this view expands the duplicate collapse, preserving every matching
source alias and freshly verifying its content. The remaining file filters apply.

Categories inferred from source folders and file extensions require review.
When `00_CATALOG/FILE_INDEX.jsonl` exists, bounded historical original-path/pack
mappings are retained; its old hashes are never trusted for duplicate decisions.
Historical mappings are information about earlier organization, not proof that
old source paths still exist. License documents are indexed, but licensing is not
inferred. Preparation, catalog export and copying stay local.

This is an organized source library. Phaser atlases/fonts and Tiled maps can need
companion files and relative paths, so reference-bearing formats are flagged.
The unique library changes names and paths; it does not rewrite references or
convert source/editor assets into runtime-ready files. Consult the aliases to
reconstruct or repair asset sets before use. See the primary
[Phaser loader documentation](https://docs.phaser.io/phaser/concepts/loader) and
[Tiled map format](https://doc.mapeditor.org/en/stable/reference/json-map-format/).

Cancellation retains generated files and writes incomplete status; copying stops
between operations and retains originals. A process exit can leave a partial
library; consult the journal and prepare a fresh library to retry. Plans are valid
for 24 hours in the current app session and cannot be executed twice. Keep existing
partial outputs until you decide how to handle them. Review free disk space for
the assets and catalogs before copying.

## Organize a model library

1. Add search folders or drives. ZIP scanning is optional; 7z and RAR additionally require a local [7-Zip installation](https://www.7-zip.org/).
2. Search filenames by default, without inheriting matches from parent folders or archives. Matching folder and ZIP/7z/RAR names appear separately; their contents are not included automatically. Choose **Paths** or **All file details** to search broader fields explicitly. Combine tags with all/any/exclude filters, mark favorites, and save searches.
Expand Down Expand Up @@ -62,6 +115,7 @@ Scanning, hashing, thumbnails, costs, and mesh tools run locally. There is no te
## Development and releases

```powershell
$env:SCOUT_RETAIN_FIXTURES = "1"
npm test
npm run build
npm run test:app
Expand All @@ -73,6 +127,18 @@ npm run release:bundle

Tests use generated fixtures and isolated profiles. They do not use a personal model library. The public release ZIP includes the executable, licenses, and corresponding source snapshots for the native importers. Distribute that complete ZIP. See [CONTRIBUTING.md](CONTRIBUTING.md), [verification](docs/VERIFICATION.md), and [importer build instructions](docs/BUILD_IMPORTERS.md).

The retained-fixture mode above omits source-removal/metadata-removal checks and
tests copying in the duplicate desktop flow. CI uses this mode. Only unset it
when deletion of generated test fixtures is authorized. Builds retain earlier
versioned frontend outputs; packaging uses only the current Vite manifest.
An existing unpacked release or release ZIP is preserved: choose a fresh output
before packaging or bundling the same version again.

The unique library is a snapshot of the selected files at preparation time.
Prepare again after adding or editing source assets; excluded duplicate aliases
are recorded as they existed when hashed. Canonical sources are rechecked during
copying. This feature does not continuously synchronize a changing directory.

Current limits: Windows x64 is the tested target; nested archives are not expanded; preview reads stop at 128 MiB; complex CAD/native application files may require their original software. Transfers are logged but do not have automatic undo. Scans skip symbolic links and junctions inside the search tree. Shape similarity, advanced mesh repair, website synchronization, and direct slicer integrations remain [future work](docs/FEATURE_RESEARCH.md).

## License and credits
Expand Down
Loading