@smartsoft001-mobilems/claude-plugins 2.112.0 → 2.114.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/package.json +1 -1
- package/plugins/mobilems/.claude-plugin/plugin.json +1 -1
- package/plugins/mobilems/skills/mobilems-articles/SKILL.md +12 -12
- package/plugins/mobilems/skills/mobilems-events/SKILL.md +1 -1
- package/plugins/mobilems/skills/mobilems-objects/SKILL.md +1 -1
- package/plugins/mobilems/skills/mobilems-objects/references/lib-contents.md +2 -2
- package/plugins/mobilems/skills/mobilems-partners/SKILL.md +2 -1
- package/plugins/mobilems/skills/mobilems-project-init/SKILL.md +1 -1
- package/plugins/mobilems/skills/mobilems-project-init/references/npm-deps.md +3 -3
- package/plugins/mobilems/skills/mobilems-project-init/references/shared-lib.md +27 -14
- package/plugins/mobilems/skills/mobilems-search/SKILL.md +6 -6
package/package.json
CHANGED
|
@@ -55,18 +55,18 @@ list — re-implementing framework code is a defect, not a shortcut:
|
|
|
55
55
|
2. [`packages/articles/README.md`](https://github.com/smartsoft001/mobilems-framework/blob/main/packages/articles/README.md) — this module's package catalog
|
|
56
56
|
3. `libs/shared/angular/README.md` — the app's own shared lib (built by `mobilems-project-init`)
|
|
57
57
|
|
|
58
|
-
| Do not hand-roll
|
|
59
|
-
|
|
|
58
|
+
| Do not hand-roll | Use |
|
|
59
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
60
60
|
| The list page logic (first read from `?filter=`/persisted filter, persistence, sort/limit/page, search tab, read guard, list mode, list SEO) | `ArticlesCatalogBaseComponent` (`super({ defaults, persistKey, listPath, searchTab, seo })`) on `createCatalog`; cycle tags: `createArticleCycleTags(this.catalog)` |
|
|
61
|
-
| The details page logic (SEO + SSR SEO, parent title, scroll, visit counter, widgets, authors, cycle tags)
|
|
62
|
-
| Card logic (image, authors, tags, `?filter=` links) and `logVisit` / `related` HTTP calls
|
|
63
|
-
| A `Masonry` `useFactory` in the module
|
|
64
|
-
| a masonry grid (`new Masonry(...)`, per-page masonry JS/CSS)
|
|
65
|
-
| filter state / hand-built `query` arrays
|
|
66
|
-
| list/detail plumbing (facade wiring, id-from-route, PDF)
|
|
67
|
-
| CMS preview logic (query params, credentialed fetch, states)
|
|
68
|
-
| media URLs, meta/OG tags, filter dictionaries, modals, WCAG
|
|
69
|
-
| a content-block renderer
|
|
61
|
+
| The details page logic (SEO + SSR SEO, parent title, scroll, visit counter, widgets, authors, cycle tags) | `ArticleDetailsBaseComponent`; related module: `createArticleRelated(id)` |
|
|
62
|
+
| Card logic (image, authors, tags, `?filter=` links) and `logVisit` / `related` HTTP calls | `ArticleCardBaseComponent`; `ArticlesService.logVisit` / `getRelated` |
|
|
63
|
+
| A `Masonry` `useFactory` in the module | `provideBrowserMasonry()` |
|
|
64
|
+
| a masonry grid (`new Masonry(...)`, per-page masonry JS/CSS) | `<smart-mobilems-masonry-grid>` (`MasonryGridComponent`) with a `#masonryContentTpl`; the `Masonry` provider only feeds it |
|
|
65
|
+
| filter state / hand-built `query` arrays | `FiltersBaseComponent<Article>` + its `FiltersContext` accessors (`searchText`, `authors`, `cycles`, `publicationDateFrom/To`, `page`, `sort`, …) |
|
|
66
|
+
| list/detail plumbing (facade wiring, id-from-route, PDF) | the `ArticlesListComponent` / `ArticlesItemComponent` base classes |
|
|
67
|
+
| CMS preview logic (query params, credentialed fetch, states) | the `ArticlesPreviewComponent` base class — the app's `/article-preview` component is view-only |
|
|
68
|
+
| media URLs, meta/OG tags, filter dictionaries, modals, WCAG | `FileUrlService`, `SeoService`/`MetaService`, `DictionaryService`, `ModalService`, `WcagService` |
|
|
69
|
+
| a content-block renderer | `WidgetComponent` + the `ArticleWidgetType` map |
|
|
70
70
|
|
|
71
71
|
Anything the framework genuinely lacks goes into `libs/shared/angular` **once** (and into its
|
|
72
72
|
README) — never a per-module copy. `scripts/verify-module.sh` fails the run on hand-rolled masonry.
|
|
@@ -141,6 +141,6 @@ article-module-specific ones:
|
|
|
141
141
|
|
|
142
142
|
- One run builds one named article module. Run the skill again — with a different name + template — for
|
|
143
143
|
each additional content type the project needs.
|
|
144
|
-
- Article modules reuse the foundation's generic `IArticleListItem` model (`@smartsoft001-mobilems/angular`) and the foundation's news carousel —
|
|
144
|
+
- Article modules reuse the foundation's generic `IArticleListItem` model (`@smartsoft001-mobilems/angular`) and the foundation's news carousel (`extends ArticlesCarouselBaseComponent`, museum template) —
|
|
145
145
|
this skill does not rebuild them.
|
|
146
146
|
- Bundled `references/` + `scripts/` ship automatically. Do not hand-edit `plugin.json`.
|
|
@@ -46,7 +46,7 @@ hardest:
|
|
|
46
46
|
| filter/search state and `query` building | `FiltersContext` via `FiltersBaseComponent` (or `QueryFilterService` for plain query strings) |
|
|
47
47
|
| confirm/cancel dialogs | `ModalService.open()` + `ModalRef` (and the shared `confirmation-modal` service) |
|
|
48
48
|
| media URLs, meta/OG tags, dictionaries, WCAG, contrast | `FileUrlService`, `SeoService`/`MetaService`, `DictionaryService`, `WcagService`, `ContrastService` |
|
|
49
|
-
| a calendar/date-picker helper duplicated per page | the shared lib's `calendar` component — built once, reused
|
|
49
|
+
| a calendar/date-picker helper duplicated per page | the shared lib's `calendar` component (`extends CalendarBaseComponent`; the museum keeps its own template) — built once, reused |
|
|
50
50
|
|
|
51
51
|
Anything the framework genuinely lacks goes into `libs/shared/angular` **once** (and into its
|
|
52
52
|
README) — never a per-module copy. `scripts/verify-module.sh` fails the run on hand-rolled masonry.
|
|
@@ -83,7 +83,7 @@ README) — never a per-module copy. `scripts/verify-module.sh` fails the run on
|
|
|
83
83
|
The cross-cutting rules live in `mobilems-project-init`
|
|
84
84
|
`references/qa-hardening.md`; these are the objects-specific ones:
|
|
85
85
|
|
|
86
|
-
- **Search debounce.** The panel full-text search (`app-objects-searchbar variant="panel"`) must
|
|
86
|
+
- **Search debounce.** The panel full-text search (`app-objects-searchbar variant="panel"`, a subclass of `SearchbarBaseComponent` with the museum's own template) must
|
|
87
87
|
re-emit through a handler with `@debounce(250)` (`lodash-decorators`) — without it every keystroke
|
|
88
88
|
hits the API. Collections and news filters already do this; keep the modules consistent.
|
|
89
89
|
- **List page:** show the total result count (`facade.totalCount()`) and add the shared
|
|
@@ -20,8 +20,8 @@ libs/museum-objects/
|
|
|
20
20
|
└── lib/
|
|
21
21
|
├── objects.module.ts # MuseumObjectsModule (references/module-and-routes.md)
|
|
22
22
|
├── objects.routes.ts
|
|
23
|
-
├── components/ # description, filter-input, high-def-request-modal,
|
|
24
|
-
│ # menu, objects-searchbar, tabs/*
|
|
23
|
+
├── components/ # description, filter-input (extends FilterInputBaseComponent), high-def-request-modal,
|
|
24
|
+
│ # menu, objects-searchbar (extends SearchbarBaseComponent), tabs/*
|
|
25
25
|
├── pages/ # list (ListComponent), item (ItemComponent) + index
|
|
26
26
|
└── services/ # objects.service.ts + index
|
|
27
27
|
```
|
|
@@ -86,7 +86,8 @@ README) — never a per-module copy. `scripts/verify-module.sh` fails the run on
|
|
|
86
86
|
## Notes
|
|
87
87
|
|
|
88
88
|
- Partners contributes nothing to `libs/shared/angular`: its grid/list cards live in its own lib, and
|
|
89
|
-
the `partners-carousel` foundation component
|
|
89
|
+
the `partners-carousel` foundation component (`extends PartnersCarouselBaseComponent`, with the
|
|
90
|
+
museum's own template) is already built by `mobilems-project-init`. So this
|
|
90
91
|
skill builds only the partners module + its route — there is no shared-components reference.
|
|
91
92
|
- This skill ONLY touches the partners module + its route. It never adds other feature modules,
|
|
92
93
|
never re-runs the foundation, and never edits `libs/shared/angular`.
|
|
@@ -129,7 +129,7 @@ component that depends only on Angular + the framework packages + other foundati
|
|
|
129
129
|
Run `python3 scripts/classify-shared-components.py` against the reference's
|
|
130
130
|
`libs/shared/angular/src/lib/components` to list which shared components are FOUNDATION (build here)
|
|
131
131
|
vs FEATURE-OWNED (built by a module skill, because they import a feature package). Build the
|
|
132
|
-
foundation components (including the home-page carousels) + the app-only services/pipes/tools
|
|
132
|
+
foundation components (including the home-page carousels; their logic comes from the framework `…BaseComponent`s, the museum writes only the template) + the app-only services/pipes/tools
|
|
133
133
|
|
|
134
134
|
- `configs.module.ts`, thread `<PREFIX>`, export them from the barrels, and build the `widget`
|
|
135
135
|
container. Models, the common pipes/directives/services/tools and the objects filter models are
|
|
@@ -28,9 +28,9 @@ foundation deps — verified against the reference):
|
|
|
28
28
|
- `@thisissoon/angular-masonry` + `masonry-layout` (masonry grids; `MasonryModule.forRoot()` in app.config;
|
|
29
29
|
`masonry-layout` is also a peer of `@smartsoft001-mobilems/angular/bootstrap`, which registers it on
|
|
30
30
|
`window` from `main.ts` — keep `allowedCommonJsDependencies: ["masonry-layout"]` in `apps/web/project.json`)
|
|
31
|
-
- `swiper` (generic `slider` component)
|
|
32
|
-
- `leaflet` + `@types/leaflet` (generic `map` component + `styles.scss` `leaflet.css` import)
|
|
33
|
-
- `openseadragon` + `@types/openseadragon` (generic `gallery/gallery-fullscreen` deep-zoom)
|
|
31
|
+
- `swiper` (generic `slider` component — `extends SliderBaseComponent`, museum template)
|
|
32
|
+
- `leaflet` + `@types/leaflet` (generic `map` component `extends MapBaseComponent` and implements `loadLeaflet()`; the framework has no `leaflet` dependency; + `styles.scss` `leaflet.css` import)
|
|
33
|
+
- `openseadragon` + `@types/openseadragon` (generic `gallery/gallery-fullscreen` deep-zoom — `extends GalleryFullscreenDialogBaseComponent`, museum template)
|
|
34
34
|
- `@angular/cdk` (`BreakpointObserver` in the home carousels; the `orientation` service)
|
|
35
35
|
- `moment` + `moment-timezone` (date handling across shared components)
|
|
36
36
|
|
|
@@ -30,7 +30,9 @@ The shared library contains two kinds of shared component, separated by a simple
|
|
|
30
30
|
This rule keeps the layering clean and lets the foundation library build on its own. The home-page
|
|
31
31
|
carousels (`new-objects-carousel`, `news-carousel`, `partners-carousel`) and the home page are
|
|
32
32
|
**foundation** shared components — they take `IObject` / `IArticleListItem` / `IPartner` from
|
|
33
|
-
`@smartsoft001-mobilems/angular` and never import a feature package, so build them here.
|
|
33
|
+
`@smartsoft001-mobilems/angular` and never import a feature package, so build them here. Each one
|
|
34
|
+
extends its framework base (`NewObjectsCarouselBaseComponent`, `ArticlesCarouselBaseComponent`,
|
|
35
|
+
`PartnersCarouselBaseComponent`) and keeps its own template.
|
|
34
36
|
|
|
35
37
|
## Identify the foundation set
|
|
36
38
|
|
|
@@ -52,7 +54,14 @@ Build everything else — `header`, `footer`, `page`, the `filter*` family, `bre
|
|
|
52
54
|
`pagination`, `searchbar`, `loader`, `error-retry`, `scroll-top`, `wcag`, `gallery`,
|
|
53
55
|
`map`, `slider`, `carousel`, the three carousels above, `category-dropdown`, `dropdown`, `menu-item`,
|
|
54
56
|
`next-page`, `calendar`, `confirmation-modal`, `newsletter-*`, `image-info-panel`, `icons`, `tabs`,
|
|
55
|
-
and the `widget` container with its foundation widgets. The
|
|
57
|
+
and the `widget` container with its foundation widgets. The logic of `calendar`, `pagination`,
|
|
58
|
+
`carousel`, the three home carousels, `slider`, `scroll-top`, `gallery` (+ fullscreen dialog),
|
|
59
|
+
`confirmation-modal`, `newsletter-modal`, `map`, the `filter-input` / `filter-date-input` /
|
|
60
|
+
`filter-custom-dictionary-input` / `filter-dictionary-input` family, `searchbar`, `catalog-toolbar`,
|
|
61
|
+
`catalog-filter-bar`, `theme-tags-filter` and `select-checkbox` is a framework base now (see
|
|
62
|
+
"Framework now → bases"): generate each as `extends …BaseComponent` (`scroll-top` extends `ScrollTopComponent`,
|
|
63
|
+
which has no `Base` suffix) and write only the museum's own template and styles — the framework
|
|
64
|
+
ships no templates. The `app` shell and `skip-links` are
|
|
56
65
|
framework components (`smart-mobilems-app`, `smart-mobilems-skip-links`) — do not copy them.
|
|
57
66
|
|
|
58
67
|
> Trust the script over this table for the **leaf** components (the grid/list cards and the
|
|
@@ -103,18 +112,22 @@ files duplicate exports that now exist; copying those is the single most common
|
|
|
103
112
|
|
|
104
113
|
Framework now — do **not** generate (import from `@smartsoft001-mobilems/angular`):
|
|
105
114
|
|
|
106
|
-
| Kind | Framework exports
|
|
107
|
-
| ------------ |
|
|
108
|
-
| environment | `createMobilemsEnvironment`, `MOBILEMS_ENVIRONMENT`, `EnvironmentService`
|
|
109
|
-
| pipes | `altText`, `fileUrl`, `backgroundUrl`, `plainText`, `stripAnchors`, `capitalize`
|
|
110
|
-
| tools | `classifyLink`, `isInternalLink`, `normalizeUrl`, `stripHtml`, `formatNamedEntries`, `normalizeSearchText`, `newTabText`, `pageToOffset`, `decodeHtmlEntities` |
|
|
111
|
-
| directives | `a[smartExternalLink]`, `[smartExternalLinks]`, `[smartFocusTrap]`, `[smartTruncatedTitle]` (references use `app…` — rename the attributes)
|
|
112
|
-
| services | `ConfirmationModalService`, `ExternalLinkConfirmationService`, `FilterPersistenceService`, `OrientationService`, `WcagChangesService`, `ContactService`, `DataService`, `MuseumSeoService`
|
|
113
|
-
| interceptors | `LanguageInterceptor`, `PreviewAuthInterceptor`, `SsrTimeoutInterceptor`, `DedupeRequestInterceptor`
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
| Kind | Framework exports |
|
|
116
|
+
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
117
|
+
| environment | `createMobilemsEnvironment`, `MOBILEMS_ENVIRONMENT`, `EnvironmentService` |
|
|
118
|
+
| pipes | `altText`, `fileUrl`, `backgroundUrl`, `plainText`, `stripAnchors`, `capitalize` |
|
|
119
|
+
| tools | `classifyLink`, `isInternalLink`, `normalizeUrl`, `stripHtml`, `formatNamedEntries`, `normalizeSearchText`, `newTabText`, `pageToOffset`, `decodeHtmlEntities`, `ElementIdSequence`, `createSafeTimeouts`, `photoFileName`/`urlExtension`, `widgetImageUrl`, `overflowingTags`, `themeTagKey`, `themeTagsLayout`, `THEME_TAGS_VISIBLE_LIMIT` |
|
|
120
|
+
| directives | `a[smartExternalLink]`, `[smartExternalLinks]`, `[smartFocusTrap]`, `[smartTruncatedTitle]` (references use `app…` — rename the attributes) |
|
|
121
|
+
| services | `ConfirmationModalService`, `ExternalLinkConfirmationService`, `FilterPersistenceService`, `OrientationService`, `WcagChangesService`, `LineHeightService`, `BreadcrumbsService`, `ContactService`, `DataService`, `MuseumSeoService` |
|
|
122
|
+
| interceptors | `LanguageInterceptor`, `PreviewAuthInterceptor`, `SsrTimeoutInterceptor`, `DedupeRequestInterceptor` |
|
|
123
|
+
| bases | `CalendarBaseComponent`, `PaginationDotsBaseComponent`, `PaginationBaseComponent`, `CarouselBaseComponent`, `PartnersCarouselBaseComponent`, `NewObjectsCarouselBaseComponent`, `ArticlesCarouselBaseComponent`, `SliderBaseComponent` (+ `ISliderOptions`; `ScrollTopComponent` is server-guarded), `GalleryBaseComponent`, `GalleryFullscreenDialogBaseComponent` (`GalleryFullscreenBaseComponent` is `@deprecated`), `ConfirmationModalBaseComponent`, `NewsletterModalBaseComponent`, `MapBaseComponent`, `FilterInputBaseComponent`, `FilterDateInputBaseComponent`, `FilterCustomDictionaryInputBaseComponent`, `FilterDictionaryInputBaseComponent` (inline tree, `source`, paging), `ThemeTagsFilterBaseComponent`, `CatalogFilterBarBaseComponent`, `CatalogToolbarBaseComponent`, `SearchbarBaseComponent`, `SelectCheckboxBaseComponent` (+ `ISelectionHooks`) |
|
|
124
|
+
| SSR tools | `injectServerResponseInit`, `appendPreloadLinks` (image preload `Link` headers) |
|
|
125
|
+
|
|
126
|
+
What stays in the app lib: the **template and styles** of every base above — the museum keeps its
|
|
127
|
+
own HTML and Tailwind classes (the filter inputs, searchbar, catalog toolbar and filter bar, theme tags and select
|
|
128
|
+
checkbox are logic only — extend the base, write the markup yourself; e.g. the confirmation-modal component is markup over `ConfirmationModalBaseComponent` /
|
|
129
|
+
`ConfirmationModalService`), the `leaflet` dependency (`MapBaseComponent` asks the subclass for
|
|
130
|
+
`loadLeaflet()`), `truncateHtml` and any museum-only tools. `local-storage`, `configs-cache`, `not-found-content` are gone: language lives in
|
|
118
131
|
the framework `TranslationService`, the config cache in `ConfigsFacade.init()`.
|
|
119
132
|
|
|
120
133
|
Adjust to what the reference actually ships, but keep the rule: one implementation, exported from the
|
|
@@ -28,12 +28,12 @@ skeleton; build the foundation with `mobilems-project-init` first.
|
|
|
28
28
|
`node_modules/@smartsoft001-mobilems/angular/README.md`)
|
|
29
29
|
2. `libs/shared/angular/README.md` — the app's own shared lib
|
|
30
30
|
|
|
31
|
-
| Do not hand-roll
|
|
32
|
-
|
|
|
33
|
-
| a tab strip
|
|
34
|
-
| result cards
|
|
35
|
-
| "next page" behaviour | the shared `NextPageComponent`, same pattern as the module lists
|
|
36
|
-
| a search input
|
|
31
|
+
| Do not hand-roll | Use |
|
|
32
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| a tab strip | `TabsComponent` / `Tab` from the shared lib (the page already imports it) |
|
|
34
|
+
| result cards | the module's own list-item components (`objects-list-item`, news/collection cards) |
|
|
35
|
+
| "next page" behaviour | the shared `NextPageComponent`, same pattern as the module lists |
|
|
36
|
+
| a search input | `app-objects-searchbar` / the shared searchbar variants — the logic is `SearchbarBaseComponent`; the museum keeps its own template |
|
|
37
37
|
|
|
38
38
|
Forking a result card for search is the classic mistake: the card then drifts
|
|
39
39
|
from the module's list and the museum ends up with two visually different
|