Két dolog volt beépítve az engine-be, ami nem az övé.
A **képtár** eddig `WarpEngine::Image` volt, pedig a modell teljesen általános:
a teletypegames-ben a tagok arcképét is ez hordozza, nem csak a katalógus
borítóit. Az `Image` modell, a feltöltött fájlok, az `/api/image/:id` végpont
és az admin oldal ezért átkerült a hosztba, az engine pedig adapteren szól
hozzá (`WarpEngine::Images`): `url_for` adja a katalógus JSON `imageUrl`-jét,
`select_options` a software-form képválasztóját, `build_from_upload` a
"tölts fel új képet" ágat. Az alapértelmezés az `Image` osztály, tehát a
default útvonal bitre a régi. A `SoftwareImage` (a katalógus-kapcsolat)
maradt az engine-ben, és **az `images` tábla nem mozdult**: az engine csak
abbahagyta a létrehozását, a generátor írja meg hoszt-kódként.
A **CI** eddig végig Woodpecker volt: kliens, aláírás-ellenőrzés,
pipeline-receptek, repo-szinkron, secret-kiosztás. Mindez egy adapter mögé
került (`WarpEngine.ci`), a Woodpecker-implementáció pedig az engine-ben
maradt `WarpEngine::CI::Woodpecker` néven — kliens, adapter, httpsig-ellenőrző
és a platformonkénti pipeline-receptek, mert a YAML-dialektus a szolgáltatóé.
Az engine saját kódja már nem nevez szolgáltatót: `CI::Repo` és `CI::Run`
értékeket kap, `CI::ConnectionError`/`ApiError`/`NotConfigured` hibákat dob, a
`Pipeline` pedig `remote_repo_id`-t ad a történelmi `woodpecker_repo_id`
kolumna fölött (a tábla itt sem mozdult). `c.ci_adapter = :none` azt jelenti,
hogy ez a hoszt nem buildel: az `/api/ci/*` 503, a `/build/config` elutasít,
az admin akciók elbújnak.
Mindkét seam a hoszt initializerében van kimondva, nem alapértelmezésre
hagyva — a hoszt megnevezi, mi a képtára és mi a CI-ja.
Törés a 0.6-hoz képest: `image_container_path`, `image_owners`,
`ci_platforms`, `ci_update_server`, `ci_extension_public_key(_url)`,
`woodpecker_url`, `woodpecker_api_token`, `woodpecker_repo_owner` és a
`WarpEngine.woodpecker_configured?` megszűnt; a helyük `c.image_class_name` /
`c.image_adapter` és `c.ci_adapter`. Az `/api/ci/*` `latest_run`/`trigger`
válasza a normalizált `CI::Run` alakot adja (number, status, branch, message,
createdAt, url), a `pipelines` lista pedig `repo_id`-t is közöl a megtartott
`woodpecker_repo_id` mellett.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Kérésre: minden magyarázó komment kikerült a forrásfájlokból — 89 Ruby, 16
TypeScript, 14 Vue, plusz a CSS/JS/CJS. Nem soralapú kereséssel: a Ruby-t a
Ripper tokenizálta, a JS/TS/CSS-t állapotgép járta végig, hogy az URL-ekben,
reguláris kifejezésekben és heredocokban álló // és # jelek helyükön
maradjanak.
Három komment maradt, mert nélkülük nem indul a kód: az entrypoint.sh
shebangja, a vite-env.d.ts hármas perjeles referenciája, és a sanitize
teszt @vitest-environment direktívája (ez utóbbi a magyarázó része nélkül).
Egy helyen kódot is kellett írni: a CommandBlock másolás-hibaágán a komment
volt a catch egyetlen tartalma, és üres blokkot az eslint nem enged — a
copied jelző visszaállítása került a helyére.
A yaml, Dockerfile, Makefile, erb és markdown fájlokat nem érintettem.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The org reorganization moved the toolchain repos to build/ but left
their container images in internal/: a package namespace does not
travel with the repo and gets no redirect, which is the only reason
the internal org was still alive.
All eight images now live under build/ — the six unchanged ones copied
layer-for-layer, the Ebitengine and Bevy ones rebuilt for the ARM
target. The internal org can be emptied.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The engines listing is a handful of curated pages, not a stream — no feed
needed. Removes the route, controller action, RssService#engines_feed and
the footer link. The WikiService#pages alias stays (blog/howtos feeds use
it).
Frontend: /engines index + /engines/:slug detail routes, nav menu item and
en/hu translations. Engine pages are few, so the index uses an emphasized
poster-style design (dark slate, emerald accents, numbered full-width cards
with content preview) instead of the blog/howtos layouts. Slugs are the last
wiki path segment, since engine pages live scattered in the wiki tree.
API: /api/rss/engines feed linking to the site's engine pages, and a
WikiService#pages alias for #index — RssService called the alias-less name,
so the blog and howtos feeds were raising NoMethodError.
- 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>
- 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>
- 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>
- 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>
- 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>