What
enlace.appmeta (~800 lines) and the catalog half of build_launcher_item exist only to serve the /_apps launcher: title/description/keyword resolution across tiers, icon resolution, favicon harvesting, the deterministic monogram. None of it is about serving apps.
A standalone package, appshelf, now does the catalog-to-page half with no dependency on a serving engine: an entry record with the catalog subset of /_apps's field names (name, display_name, description, keywords, icon_url, launchable, launch_url, updated_at), and a renderer that produces a relocatable static page plus a shelf.json. Its icon rendering (glyph, monogram, gradient) was copied from enlace.appmeta, with provenance noted.
Proposed, once appshelf is public on PyPI
build_launcher_item produces the appshelf record for the catalog fields and adds enlace's serving fields (route, api_route, has_frontend, has_api, access) on top — one definition of the record instead of two.
- Delete the copied icon rendering from
enlace.appmeta in favour of appshelf's.
- Keep harvesting (reading an app's own
app.toml, manifest, <head>, package.json) in enlace for now: it needs an app directory, which is enlace's concept. It can move later as a producer of appshelf records.
Dependency direction: enlace → appshelf, never the reverse.
Not in scope
Access filtering stays in enlace. appshelf deliberately never decides who sees what — see #35 for why visibility computed apart from authorization drifts.
What
enlace.appmeta(~800 lines) and the catalog half ofbuild_launcher_itemexist only to serve the/_appslauncher: title/description/keyword resolution across tiers, icon resolution, favicon harvesting, the deterministic monogram. None of it is about serving apps.A standalone package, appshelf, now does the catalog-to-page half with no dependency on a serving engine: an entry record with the catalog subset of
/_apps's field names (name,display_name,description,keywords,icon_url,launchable,launch_url,updated_at), and a renderer that produces a relocatable static page plus ashelf.json. Its icon rendering (glyph, monogram, gradient) was copied fromenlace.appmeta, with provenance noted.Proposed, once appshelf is public on PyPI
build_launcher_itemproduces the appshelf record for the catalog fields and adds enlace's serving fields (route,api_route,has_frontend,has_api,access) on top — one definition of the record instead of two.enlace.appmetain favour of appshelf's.app.toml, manifest,<head>,package.json) in enlace for now: it needs an app directory, which is enlace's concept. It can move later as a producer of appshelf records.Dependency direction: enlace → appshelf, never the reverse.
Not in scope
Access filtering stays in enlace. appshelf deliberately never decides who sees what — see #35 for why visibility computed apart from authorization drifts.