273 Commits
Author SHA1 Message Date
mr.zero b09610bc33 Rewrite WarpEngine README for standalone consumers
ci/woodpecker/push/woodpecker Pipeline was successful
The README is what the tools/warp_engine mirror shows: present the engine as
a standalone product installed from git or the gem registry, with the
monorepo workflow reduced to a short Development note.
2026-08-04 20:16:46 +02:00
mr.zeroandClaude Fable 5 211dcccbf3 Trim whitespace from the forge token before use
ci/woodpecker/manual/woodpecker Pipeline was successful
A trailing newline pasted into the Woodpecker secret broke the push URL
("credential url cannot be parsed"); strip all whitespace from the token in
both the mirror and the gem-publish steps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 20:07:13 +02:00
mr.zeroandClaude Fable 5 b1b619befa Allow manual pipeline runs for the split mirror
ci/woodpecker/manual/woodpecker Pipeline failed
Path-filtered push events hide the workflow for unrelated pushes and manual
restarts have no changed-files list; add event: manual so the mirror can be
triggered from the Woodpecker UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 20:03:35 +02:00
mr.zeroandClaude Fable 5 af779b0988 Fix YAML parse error in the gem-publish step
The credentials printf line contains ': ' which YAML reads as a mapping;
use a literal block scalar for that command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:57:15 +02:00
mr.zeroandClaude Fable 5 b4d0198d2a Add CI split-mirror pipeline for WarpEngine
- .woodpecker.yaml: on master pushes touching libs/ruby/warp_engine, split the
  subtree and force-push it to the read-only tools/warp_engine mirror; on
  warp_engine-v* tags, build and push the gem to the Forgejo rubygems registry
- engine README documents the monorepo-first workflow and the mirror

Requires a `forge_token` Woodpecker secret (repository:write + package:write).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:47:15 +02:00
mr.zeroandClaude Fable 5 516f724f01 Rewrite READMEs in English for the WarpEngine split
- root README: monorepo layout with libs/, the WarpEngine/host layering,
  rebuild note for the root build context, make api-test and snapshot docs
- warp_engine README translated to English

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:36:40 +02:00
mr.zeroandClaude Fable 5 4d1e04afdf Phase 6: polish — apipie matcher, install generator, engine migrations, docs
- host apipie matcher now globs the engine controllers, so /api/docs and
  /api/swagger keep documenting the catalog endpoints
- rails g warp_engine:install: initializer template + a clean
  create_warp_engine_tables migration (signed bigint PKs) for new hosts;
  TTG never runs it
- engine append_migrations initializer: future catalog migrations in the
  engine's db/migrate run via the host's rails db:migrate
- README documents the updater contract, config surface, host expectations
  (admin JS picker, apipie matcher) and the soft-delete/resurrection behavior
- make api-test runs both suites plus a production zeitwerk:check

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:21:40 +02:00
mr.zeroandClaude Fable 5 d2b4b67e44 Phase 5: ship the catalog ActiveAdmin resources from the engine
- the 7 catalog admin files (softwares, releases, external_links,
  platform_links, images, files page, downloads) move to the engine's
  app/admin; the host ActiveAdmin instance loads them via
  ActiveAdmin.application.load_paths (single admin, URLs unchanged)
- engine initializers: Zeitwerk ignore for app/admin (production eager load)
  and load_paths + watchable_dirs registration, guarded by defined?(ActiveAdmin)
  so the admin-less dummy app boots
- images admin reads image owners from WarpEngine.config.image_owners; the
  host registers the Member owner in config/initializers/warp_engine.rb;
  the interim ImageUsage registry is gone
- fix: SoftwareImage.distinct.pluck clashed with its order(:position)
  default scope on MySQL (unscope(:order)) — introduced in phase 0, caught
  by the first authenticated /admin/images smoke test
- files page: download links use the public /file/ URL instead of the raw
  container path; the picker's stored path comes from config

Verified: both suites green, zeitwerk:check (production) clean, JSON
baselines intact, authenticated admin smoke test on every page incl.
the 3-level nested software form and Files picker mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:18:28 +02:00
mr.zeroandClaude Fable 5 b79a73d62d Phase 4: move catalog controllers and routes into WarpEngine
- update, files and the 6 /api catalog controllers now live in the engine on
  a new WarpEngine::ApiController base (same rescue/mime behavior as host)
- engine routes serve /update, /file/*path, /api/software*, /api/builds*,
  /api/image/:id, /api/download at unchanged public paths via the root mount;
  host routes keep only TTG endpoints (events, members, wiki, rss, swagger)
- /update secret comes from WarpEngine.config.update_secret and an
  unconfigured secret now rejects every request (previously an empty
  UPDATE_SECRET env accepted empty secrets)
- apipie-rails is an engine dependency (DSL in engine controllers); dummy app
  configures apipie with validation off, mirroring the host
- engine request specs: catalog controller specs moved from host plus new
  /update auth contract spec

Verified: engine suite 53 green, host suite 6 green, /api/software and
/api/builds byte-identical to baselines, /update 401/400 behavior intact,
admin and TTG endpoints OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:09:11 +02:00
mr.zeroandClaude Fable 5 0dc3cebc14 Phase 3: move service layer, serializers and DTOs into WarpEngine + dummy-app test suite
- all catalog services (update/software/highlighted/builds/file/file-manager/
  download/image + SoftwareResponseBuilder), the SoftwareUpdater platform
  services and their concerns, Blueprinter serializers (incl. TimestampFields)
  and the 4 DTOs now live in the engine under WarpEngine::
- constantize dispatch strings use absolute names
  (WarpEngine::SoftwareUpdater::<Platform>Service)
- container paths read from WarpEngine.config everywhere (FileService,
  DownloadService, FileManagerService, ArchiveExtraction, ReleaseSerializer
  path rewriting); FileManagerService base path is now lazy
- engine requires blueprinter itself; gemspec declares blueprinter + rubyzip
- engine test suite: spec/dummy app (mysql warp_engine_test, catalog-only
  schema), rails_helper with engine-local factories; catalog model/service
  specs and factories moved from the host
- host suite keeps TTG specs and loads catalog factories from the engine

Verified: engine suite 40 green, host suite 14 green, /api/software and
/api/builds byte-identical to baselines, admin OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 19:03:58 +02:00
mr.zeroandClaude Fable 5 92f10197c1 Phase 2: move the 8 catalog models into the WarpEngine engine
- Software, Release, ReleaseAsset, ExternalLink, PlatformLink, Image,
  SoftwareImage, Download now live in the engine under WarpEngine::, on top
  of WarpEngine::ApplicationRecord; table names unchanged (empty prefix)
- each model runs an ActiveSupport load hook (:warp_engine_<model>) as a
  host extension point
- WarpEngine::Image reads its upload path from WarpEngine.config
- host references fully qualified (services, serializers, admin, specs);
  admin registrations renamed with as: so /admin URLs and route helpers are
  byte-identical; factories pinned to the namespaced classes
- Member#image now class_name: "WarpEngine::Image"

Verified: full suite green, /api/software and /api/builds byte-identical to
the phase-0 baselines, admin routes unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 18:51:12 +02:00
mr.zeroandClaude Fable 5 2f6cc4cdc2 Phase 1: warp_engine gem skeleton (path gem, mounted engine)
- libs/ruby/warp_engine: gemspec, WarpEngine::Engine (isolate_namespace with
  empty table_name_prefix), WarpEngine.configure surface (container paths,
  update_secret, image_owners), empty engine routes
- host Gemfile: path gem; host routes: mount WarpEngine::Engine => "/" as
  the last entry so host routes always win
- docker: api build context moved to repo root so libs/ is visible at
  bundle-install time; ./libs:/libs runtime mount; root .dockerignore to keep
  data/ and node_modules out of the build context

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 18:44:32 +02:00
mr.zeroandClaude Fable 5 bf921c589d Phase 0: in-place decoupling before WarpEngine extraction
- FileService/DownloadService: lazy container-path resolution instead of
  class-load-time realpath (boot no longer requires /softwares to exist)
- downloadCount/totalDownloads: single grouped query passed as Blueprinter
  option instead of per-release association counts (fixes N+1)
- admin Images: Member coupling replaced with ImageUsage owner registry
  (precursor of the WarpEngine.config.image_owners hook)
- Image: UPLOAD_PATH constant replaced with call-time upload_path accessor
- proper test environment (config/environments/test.rb, softwares_test DB,
  hosts.clear) — suite previously ran against the development DB
- spec fixes: case-insensitive uniqueness matchers (MySQL ai_ci collation),
  DB-cascade has_many expectations, PlatformLink::SUPPORTED_PLATFORMS
- JSON baselines of /api/software and /api/builds for post-extraction diffing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 18:39:20 +02:00
Zsolt Tasnadi 0f13c19fc8 schema update 2026-08-04 15:47:49 +02:00
mr.zero 724e5bc748 refact round 2026-08-04 15:45:13 +02:00
mr.zero 24ba77a0f2 Back to Catalog label fix 2026-08-04 12:11:37 +02:00
Zsolt Tasnadi 27feec9b8a schema update 2026-08-04 10:52:00 +02:00
mr.zero 46c51bb317 platform links 2026-08-04 10:49:02 +02:00
mr.zero ddab4b9ff5 remove duplicated play button 2026-08-04 10:43:38 +02:00
mr.zero 1a2430b321 more faicons system wide 2026-08-04 10:29:40 +02:00
mr.zero 43994d73b0 move build matrix menu item to bottom 2026-08-04 10:19:34 +02:00
mr.zero 91fbf66b1d more fa icons for matrix 2026-08-04 10:14:34 +02:00
mr.zero 4eddea1ff2 fa icons for matrix 2026-08-04 10:12:19 +02:00
mr.zero 0eb507a977 matrix colors 2026-08-04 10:07:01 +02:00
mr.zero 8b72599b3b build matrix mobile view 2026-08-04 08:47:35 +02:00
mr.zero 5c98ab5983 Back to Catalog arrow fix 2026-08-04 08:45:33 +02:00
mr.zero a64234fa74 matrix header tweaks 2026-08-04 08:44:00 +02:00
mr.zero 77f269d9e0 build concerns, build matrix 2026-08-04 08:37:49 +02:00
mr.zero f943357ebd custom css classes 2026-08-04 07:08:08 +02:00
mr.zero e5f714c34e catalog index mobile view fix 2026-08-04 06:57:14 +02:00
mr.zero 536a1b4c09 release asset mobile view 2026-08-04 06:54:43 +02:00
mr.zeroandClaude Fable 5 da37e39774 Make docs optional in the tic80 updater
Older-style tic80 pipelines (bombexpert, mranderson) do not upload a
docs zip; the unconditional extraction raised and aborted the whole
update, so the new binary assets never got registered. Extract and
register docs only when the zip/dir exists. Covered by new
Tic80Service specs (optional docs + binary slug pickup).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 23:46:50 +02:00
mr.zero 4b03b7bbc7 retro mode fix 2026-08-03 22:30:53 +02:00
mr.zero d45b0e6800 catalog show hero fix 2026-08-03 22:25:03 +02:00
mr.zero 30f36cb7c6 platform fa icons 2026-08-03 22:19:39 +02:00
mr.zero b69c307e0a more fa icons 2026-08-03 22:16:58 +02:00
mr.zero bd26c4be63 faicons 2026-08-03 22:07:55 +02:00
mr.zero caaec14708 favicon 2026-08-03 21:46:00 +02:00
mr.zero 42b083596e PlatformBadge 2026-08-03 21:39:51 +02:00
mr.zero c413640427 asset table fix 2026-08-02 22:58:24 +02:00
mr.zero 242c808add web payable and asset view 2026-08-02 22:54:37 +02:00
mr.zero 73cc567e1f binary assets for frontend 2026-08-02 18:45:08 +02:00
mr.zero 1a92978df4 drop legacy path columns 2026-08-02 18:31:55 +02:00
mr.zero c630278e42 release assets 2026-08-02 18:26:29 +02:00
mr.zero 9db8ff189c update concerns 2026-08-02 12:58:31 +02:00
mr.zeroandClaude Fable 5 4cc05ee586 Support repo metadata field as Repository external link
All software updater services now read an optional repo field from the
game metadata and upsert it as a "Repository" external link, keyed by
(software_id, label) so re-deploys update the existing link instead of
creating duplicates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 11:18:13 +02:00
mr.zero a275b5e72a add bevy and phaser engine support 2026-07-31 18:36:12 +02:00
mr.zero e37e3760ac godot support 2026-07-31 16:33:51 +02:00
mr.zero 9a3347cfe7 remove emoji from admin menu 2026-07-29 20:26:16 +02:00
mr.zero a170eff37a isAdmin trick 2026-07-29 13:27:39 +02:00