@smartsoft001-mobilems/claude-plugins 2.120.0 → 2.121.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,6 +20,7 @@ Run them in this order for a new museum app — `/smart:scaffold-nx-workspace`
20
20
  | `mobilems-project-init` | The MobilEMS foundation: deps, Tailwind, runtime env, `app.config` providers, shared lib, static pages, app shell, `.claude`. No feature modules. |
21
21
  | `mobilems-objects` | `libs/museum-objects` + the `/obiekty` route |
22
22
  | `mobilems-object-collections` | `libs/museum-collections` + the `/kolekcje` route |
23
+ | `mobilems-creators` | `libs/museum-creators` + the creators route (`/tworcy` or `/artysci`) and the creators search tab |
23
24
  | `mobilems-articles` | A parametrized (NAME + TEMPLATE) article module — news, education, … |
24
25
  | `mobilems-thematic-publications` | `libs/museum-thematic-paths` + the `/sciezki-tematyczne` route |
25
26
  | `mobilems-events` | `libs/museum-events` + the `/wydarzenia` route (booking flow) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartsoft001-mobilems/claude-plugins",
3
- "version": "2.120.0",
3
+ "version": "2.121.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -13,6 +13,7 @@ Run order for a new museum app: `/smart:scaffold-nx-workspace` → `mobilems-pro
13
13
  | Skill | `mobilems-project-init` | The MobilEMS foundation — deps, Tailwind, SSR + translations runtime, `app.config` providers, shared lib, static pages, app shell, `.claude`. Produces NO feature modules |
14
14
  | Skill | `mobilems-objects` | Museum objects module — `libs/museum-objects` (domain + shell/angular) + the `/obiekty` route |
15
15
  | Skill | `mobilems-object-collections` | Collections module — `libs/museum-collections` + the `/kolekcje` route |
16
+ | Skill | `mobilems-creators` | Creators (artists) — `libs/museum-creators` + the creators route and search tab |
16
17
  | Skill | `mobilems-articles` | A parametrized (NAME + TEMPLATE) article-backed content module; run once per content type |
17
18
  | Skill | `mobilems-thematic-publications` | Thematic paths — `libs/museum-thematic-paths` + the `/sciezki-tematyczne` route |
18
19
  | Skill | `mobilems-events` | Events + booking flow — `libs/museum-events` + the `/wydarzenia` route |
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "mobilems",
3
3
  "description": "MobilEMS-specific Claude Code skills (MuzaCMS / MobileMS indexer API)",
4
- "version": "2.120.0"
4
+ "version": "2.121.0"
5
5
  }
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: mobilems-creators
3
+ description: Add the museum CREATORS (artists) feature module to a MobilEMS app initialized with mobilems-project-init. Use whenever the user wants to add / scaffold / wire the creators module, the artists index (letters, groups, jump-to), the filtered artists list, the creator details page, the creator card, or the artists tab of the global search, or asks to "dodaj moduł twórców / artystów". Creates libs/museum-creators (or the museum's own name, e.g. museum-artists), registers the creators route (/tworcy or /artysci), and adds the creators npm packages. Requires the MobilEMS foundation to exist first.
4
+ user-invocable: true
5
+ allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
6
+ ---
7
+
8
+ # MobilEMS creators module
9
+
10
+ Add the **creators** (twórcy / artyści) feature module to a MobilEMS app whose foundation was built by
11
+ `mobilems-project-init`. This skill builds the `libs/museum-creators` library (the museum may name it
12
+ `museum-artists`), its routes and its pages on top of the framework bases, and wires the creators path and the
13
+ search tab.
14
+
15
+ The framework shares **logic only**: every page is an `@Directive() abstract class` with no template. The museum
16
+ writes its own HTML and styles. There is no generator (one reference consumer, so YAGNI): the library is written by
17
+ hand from the reference below.
18
+
19
+ ## Precondition
20
+
21
+ The MobilEMS foundation must exist (`SharedModule.forRoot` in `app.config.ts`, a populated shared-lib barrel). If it
22
+ does not, tell the user to run `/mobilems:project-init` first. Ask the user for:
23
+
24
+ - the library name (default `museum-creators`) and the route (`/tworcy`, or `/artysci` as in sztuki);
25
+ - the museum's API host. **The index base needs the prefixes endpoint and `lastNameSw`, which only the staging
26
+ API has** (`api-muza.muzeumsztuki.pl` does not). Without them build the list on `CreatorsCatalogBaseComponent`
27
+ (see the README's "Which list base?").
28
+
29
+ The reference is the sztuki museum's `libs/museum-artists` (routes, pages, templates, search tab). Read it for the
30
+ templates; take the logic from the framework bases. Its artist page (MOB-1972/1963) was ported into
31
+ `CreatorDetailsBaseComponent` from sztuki `8f698f6`, but sztuki's own `item.component` does not extend the base yet:
32
+ copy its template, not its class.
33
+
34
+ ## Framework first — MANDATORY
35
+
36
+ Read these before writing ANY component, service, pipe, directive or helper, and reuse what they
37
+ list — re-implementing framework code is a defect, not a shortcut:
38
+
39
+ 0. [**The Framework API index**](https://github.com/smartsoft001/mobilems-framework/blob/main/README.md#-framework-api) — the map of every package to
40
+ its catalog. Start here when you do not already know which package owns what.
41
+ 1. The framework API catalog — `packages/shared/angular/README.md` in this repo, installed as
42
+ `node_modules/@smartsoft001-mobilems/angular/README.md` in a museum app ([browse](https://github.com/smartsoft001/mobilems-framework/blob/main/packages/shared/angular/README.md)).
43
+ 2. [`packages/creators/README.md`](https://github.com/smartsoft001/mobilems-framework/blob/main/packages/creators/README.md) — this module's package catalog: services, URL tools, the bases,
44
+ the "Which list base?" table and the API notes
45
+ 3. `libs/shared/angular/README.md` — the app's own shared lib (built by `mobilems-project-init`)
46
+
47
+ | Do not hand-roll | Use |
48
+ | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
49
+ | the creators HTTP calls, letter filtering, id normalisation | `CreatorsService` (`getPage`, `getAll`, `getByLetter`, `getPrefixes`, `getByIndexPrefix`, `getById`, `getWorks`, `getRelated`) |
50
+ | the letter index: letters, two-letter groups, `#fragment`, focus | `CreatorsIndexBaseComponent` |
51
+ | the mobile "go to" panel | `CreatorsJumpToBaseComponent` |
52
+ | the filtered list (name, birth range, sort, paging) | `CreatorsCatalogBaseComponent` + `CreatorsFiltersBaseComponent` (modal) |
53
+ | the creator card (name, years, roles, image, link) | `CreatorCardBaseComponent` |
54
+ | the details page (biography fold, portrait, related strips, contents, share, prev/next, SEO) | `CreatorDetailsBaseComponent` |
55
+ | the search tab (phrase, paging, page size) | `CreatorsSearchListBaseComponent` |
56
+ | query urls, name/roles/years formatting, letter grouping, details link | `creatorsListUrl`, `creatorDisplayName`, `creatorRoles`, `groupCreatorsByLetter`, `creatorDetailsCommands` |
57
+ | a masonry grid | `<smart-mobilems-masonry-grid>` (`MasonryGridComponent`), with `provideBrowserMasonry()` |
58
+ | meta / OG tags, media urls | `MuseumSeoService` (the bases call it), `FileUrlService` (the card and details call it) |
59
+
60
+ Anything the framework genuinely lacks goes into `libs/shared/angular` **once** (and into its README) — never a
61
+ per-module copy.
62
+
63
+ ## Steps
64
+
65
+ 1. **npm deps** — add `@smartsoft001-mobilems/creators-domain`, `@smartsoft001-mobilems/creators-shell-angular`,
66
+ `@smartsoft001-mobilems/creators-shell-dtos` (match the installed mobilems line). The details base types works as
67
+ `MsObject`, so `@smartsoft001-mobilems/objects-domain` must be present too. Resolve versions at run time; do not
68
+ `npm install` unless asked.
69
+ 2. **Library** — create `libs/museum-creators` with a `shell/angular` project (sztuki's `museum-artists` has one) and the tsconfig path
70
+ `@<PREFIX>/museum-creators/shell/angular`, mirroring the other `libs/museum-*` libs. The models come from the
71
+ framework packages, so the museum needs no domain project of its own.
72
+ 3. **Routes** — the module routes, in this order (the details page takes the canonical `:id/:slug` and the bare `:id`):
73
+
74
+ ```ts
75
+ export const routes: Route[] = [
76
+ { path: ':id/:slug', component: ItemComponent },
77
+ { path: ':id', component: ItemComponent },
78
+ { path: '', component: ListComponent },
79
+ ];
80
+ ```
81
+
82
+ Register the lazy route in `apps/web/src/app/app.routes.ts` (`/tworcy` or `/artysci`).
83
+
84
+ 4. **Pages** — each extends a framework base; the museum supplies the template. Overridable members are read lazily,
85
+ so declare them as `protected override readonly`:
86
+ - `ListComponent extends CreatorsIndexBaseComponent`: override `creatorsIndexAnchorBase` (default `'tworcy'`; the
87
+ museum's route name, so `#Ba` links match) and `creatorsIndexSeo` (an `ICreatorsListSeo` with the museum's
88
+ translation keys). Put the button that opens the jump-to panel under the `#filtersButton` template ref. Its
89
+ template shows the results view while the base's `filtered()` is `true` and the letter index otherwise; do not
90
+ re-parse `?filter=` yourself.
91
+ - `ResultsComponent extends CreatorsCatalogBaseComponent` for `?filter=`: `super({ persistKey, listPath, seo })`.
92
+ Pair it with `FiltersComponent extends CreatorsFiltersBaseComponent` (do not bind Escape again, the base does).
93
+ Bind the modal's `(applied)` to `applyFilter($event)`: it navigates to `listPath?filter=…` (the url is the source
94
+ of truth); "reset filters" is `clearAllFilters()`, which navigates back to the index.
95
+ Offer only the filters the API supports: **name and birth date from-to** (no death date, collection or tags).
96
+ - `IndexFiltersMobileComponent extends CreatorsJumpToBaseComponent` (the jump-to panel; override
97
+ `creatorsJumpToHeaderSelectors` if the header tags differ from `app-header` / `app-nav-bar`).
98
+ - `ArtistCardComponent extends CreatorCardBaseComponent`: override `creatorCardPath` (default `'/tworcy'`) and
99
+ `creatorCardPlaceholder` (default `'/gfx/no-image.png'`).
100
+ - `ItemComponent extends CreatorDetailsBaseComponent`: override `creatorDetailsPath` (start it with `/`) and
101
+ `creatorDetailsKeys` (`{ ...CREATOR_DETAILS_KEYS, ... }` with the museum's label and SEO title keys); sanitize
102
+ the biography html where the template binds it. For result cards in the related strips, set the type parameter
103
+ (`CreatorDetailsBaseComponent<SearchResultCard>`) and override `creatorDetailsRelatedItem(item, key)`. Tailwind
104
+ class strings stay in the component; the base has none.
105
+ 5. **Search tab** — in `app.config.ts` set `SEARCH_CONFIG_TOKEN` to `{ apiUrl, creators: true }` (adds the creators
106
+ count; skip it when your `searchMap` already returns a `creators` url, as sztuki's does, since `searchMap` wins
107
+ anyway), add a `searchRoutes` module for `/wyszukaj/:text/artysci` whose `SearchListComponent` extends
108
+ `CreatorsSearchListBaseComponent` (the `#results` template ref is the scroll target), and register it as a child of
109
+ the `wyszukaj/:text` route (sztuki also lists it in its `SEARCH_SECTIONS`). See `mobilems-search` for the frame.
110
+ 6. **Section links** — provide `PAGE_SECTION_ROUTES_TOKEN` as `{ ...DEFAULT_PAGE_SECTION_ROUTES, creatorsPath: '/artysci' }`
111
+ so a CMS "creator" target goes to `[creatorsPath, id]` instead of the objects filter.
112
+ 7. **Translations** — add the keys the museum's templates and overrides use (`ARTISTS.*` / `CREATORS.*`, the SEO
113
+ keys) for BOTH `pl` and `en`; run `npm run check:translations`.
114
+ 8. **Verify** — `npx nx build web` (production), the lib's lint and tests, and open `/artysci`, a letter, a
115
+ `#fragment` link (`/artysci#Ba`), `?filter=`, a details page with prev/next, and the search tab.
116
+
117
+ ## Known pitfalls
118
+
119
+ - **Empty `q=` / `sw=` empties the list (404).** Always go through `creatorsListUrl` / the service.
120
+ - **Prefixes endpoint and `lastNameSw` are staging-only**; on `api-muza.muzeumsztuki.pl` the index base shows nothing
121
+ useful. Check the API before choosing the index base.
122
+ - **Death-date range does not work** (the API always answers 404); collection and tags filters are ignored. Leave
123
+ them out of the filters modal and report them.
124
+ - **Works 404 means none**: do not show an error for a creator without works.
125
+ - **`creator/{id}` is staging-only**: `getById` reads it and falls back to `dictionary/Creator/{id}` on a 404, so the
126
+ details page works on both hosts, but the portrait, lead artwork, tags, editorial biography and the exhibitions,
127
+ archives and MS books strips need the profile endpoint. Their parts simply do not render without it.
128
+ - **Prev/next** exist only after a list was shown (`CreatorsListContext`); a deep link has none. Hide the buttons.
129
+ - **Member name clashes**: the bases prefix their private members (`creators…`, `creator…`) so that a subclass can
130
+ keep its own `route`, `router`, `document`, `translate`. Keep your own names unprefixed and do not reuse a base
131
+ prefix; a clash shows up as TS2415 in `nx build`, not in Jest.
132
+ - **SSR**: scrolling, focus and the `#fragment` run only in the browser; use the injected `DOCUMENT`, never the
133
+ `document` global.
134
+
135
+ ## Notes
136
+
137
+ - This skill builds only the creators module. It never adds other feature modules and never re-runs the foundation.
138
+ - Bundled files ship automatically. Do not hand-edit `plugin.json`.
@@ -49,6 +49,11 @@ representations of the same object.
49
49
  `wyszukaj/:text` (its search module) and the page builds its tab list from
50
50
  what is registered. When a tab is missing, fix it in that module's skill
51
51
  scope, not by hardcoding the tab here.
52
+ **Creators tab.** Set `creators: true` in `SEARCH_CONFIG_TOKEN` (default `false`): `SearchService` then also counts
53
+ `creators` (`dictionary/Creator/search/page/1?maxPerPage=1&q=…`, `ISearchResults.creators`); `searchMap` still
54
+ overrides the url. The tab's page extends `CreatorsSearchListBaseComponent`
55
+ (`@smartsoft001-mobilems/creators-shell-angular`, route `wyszukaj/:text/artysci`); the museum writes the view.
56
+ Build the module with `mobilems-creators`.
52
57
  3. **Direct navigation to a tab must work.** Opening `/wyszukaj/wazy/aktualnosci`
53
58
  straight from a link — not by clicking through — has to land on that tab with
54
59
  results loaded. This broke repeatedly (MOB-1052…1056) because the active tab