@smartsoft001-mobilems/claude-plugins 2.85.0 → 2.87.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.
Files changed (176) hide show
  1. package/.claude-plugin/marketplace.json +2 -6
  2. package/package.json +2 -2
  3. package/plugins/mobilems/.claude-plugin/README.md +30 -0
  4. package/plugins/mobilems/.claude-plugin/plugin.json +5 -0
  5. package/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh +372 -0
  6. package/plugins/mobilems/skills/mobilems-articles/SKILL.md +84 -0
  7. package/plugins/mobilems/skills/mobilems-articles/references/lib-contents.md +164 -0
  8. package/plugins/mobilems/skills/mobilems-articles/references/module-and-routes.md +146 -0
  9. package/plugins/mobilems/skills/mobilems-articles/references/shared-components.md +56 -0
  10. package/plugins/mobilems/skills/mobilems-articles/scripts/detect-init.sh +29 -0
  11. package/plugins/mobilems/skills/mobilems-articles/scripts/verify-module.sh +61 -0
  12. package/plugins/mobilems/skills/mobilems-docs-reader/SKILL.md +116 -0
  13. package/plugins/mobilems/skills/mobilems-events/SKILL.md +65 -0
  14. package/plugins/mobilems/skills/mobilems-events/references/lib-contents.md +212 -0
  15. package/plugins/mobilems/skills/mobilems-events/references/module-and-routes.md +113 -0
  16. package/plugins/mobilems/skills/mobilems-events/scripts/detect-init.sh +29 -0
  17. package/plugins/mobilems/skills/mobilems-events/scripts/verify-module.sh +59 -0
  18. package/plugins/mobilems/skills/mobilems-object-collections/SKILL.md +52 -0
  19. package/plugins/mobilems/skills/mobilems-object-collections/references/lib-contents.md +76 -0
  20. package/plugins/mobilems/skills/mobilems-object-collections/references/module-and-routes.md +116 -0
  21. package/plugins/mobilems/skills/mobilems-object-collections/references/shared-components.md +61 -0
  22. package/plugins/mobilems/skills/mobilems-object-collections/scripts/detect-init.sh +29 -0
  23. package/plugins/mobilems/skills/mobilems-object-collections/scripts/verify-module.sh +44 -0
  24. package/plugins/mobilems/skills/mobilems-objects/SKILL.md +52 -0
  25. package/plugins/mobilems/skills/mobilems-objects/references/lib-contents.md +68 -0
  26. package/plugins/mobilems/skills/mobilems-objects/references/module-and-routes.md +108 -0
  27. package/plugins/mobilems/skills/mobilems-objects/references/shared-components.md +69 -0
  28. package/plugins/mobilems/skills/mobilems-objects/scripts/detect-init.sh +29 -0
  29. package/plugins/mobilems/skills/mobilems-objects/scripts/verify-module.sh +51 -0
  30. package/plugins/mobilems/skills/mobilems-partners/SKILL.md +65 -0
  31. package/plugins/mobilems/skills/mobilems-partners/references/lib-contents.md +160 -0
  32. package/plugins/mobilems/skills/mobilems-partners/references/module-and-routes.md +125 -0
  33. package/plugins/mobilems/skills/mobilems-partners/scripts/detect-init.sh +29 -0
  34. package/plugins/mobilems/skills/mobilems-partners/scripts/verify-module.sh +59 -0
  35. package/plugins/mobilems/skills/mobilems-project-init/SKILL.md +134 -0
  36. package/plugins/mobilems/skills/mobilems-project-init/references/app-shell.md +107 -0
  37. package/plugins/mobilems/skills/mobilems-project-init/references/claude-config.md +44 -0
  38. package/plugins/mobilems/skills/mobilems-project-init/references/config-providers.md +203 -0
  39. package/plugins/mobilems/skills/mobilems-project-init/references/npm-deps.md +66 -0
  40. package/plugins/mobilems/skills/mobilems-project-init/references/server-env.md +89 -0
  41. package/plugins/mobilems/skills/mobilems-project-init/references/shared-lib.md +125 -0
  42. package/plugins/mobilems/skills/mobilems-project-init/references/tailwind-styles.md +106 -0
  43. package/plugins/mobilems/skills/mobilems-project-init/scripts/classify-shared-components.py +114 -0
  44. package/plugins/mobilems/skills/mobilems-project-init/scripts/detect-base.sh +49 -0
  45. package/plugins/mobilems/skills/mobilems-project-init/scripts/verify-init.sh +73 -0
  46. package/plugins/mobilems/skills/mobilems-thematic-publications/SKILL.md +60 -0
  47. package/plugins/mobilems/skills/mobilems-thematic-publications/references/lib-contents.md +134 -0
  48. package/plugins/mobilems/skills/mobilems-thematic-publications/references/module-and-routes.md +107 -0
  49. package/plugins/mobilems/skills/mobilems-thematic-publications/scripts/detect-init.sh +29 -0
  50. package/plugins/mobilems/skills/mobilems-thematic-publications/scripts/verify-module.sh +56 -0
  51. package/plugins/flow/.claude-plugin/README.md +0 -91
  52. package/plugins/flow/.claude-plugin/merge-permissions.js +0 -97
  53. package/plugins/flow/.claude-plugin/plugin.json +0 -5
  54. package/plugins/flow/.claude-plugin/settings.template.json +0 -86
  55. package/plugins/flow/agents/angular-component-scaffolder.md +0 -175
  56. package/plugins/flow/agents/angular-directive-builder.md +0 -153
  57. package/plugins/flow/agents/angular-guard-builder.md +0 -243
  58. package/plugins/flow/agents/angular-jest-test-writer.md +0 -474
  59. package/plugins/flow/agents/angular-pipe-builder.md +0 -169
  60. package/plugins/flow/agents/angular-resolver-builder.md +0 -286
  61. package/plugins/flow/agents/angular-service-builder.md +0 -161
  62. package/plugins/flow/agents/angular-signal-state-builder.md +0 -339
  63. package/plugins/flow/agents/angular-test-diagnostician.md +0 -279
  64. package/plugins/flow/agents/angular-testbed-configurator.md +0 -315
  65. package/plugins/flow/agents/arch-scaffolder.md +0 -278
  66. package/plugins/flow/agents/e2e-data-testid-injector.md +0 -197
  67. package/plugins/flow/agents/e2e-project-scaffolder.md +0 -194
  68. package/plugins/flow/agents/e2e-test-writer.md +0 -350
  69. package/plugins/flow/agents/shared-agent-evolver.md +0 -294
  70. package/plugins/flow/agents/shared-build-verifier.md +0 -160
  71. package/plugins/flow/agents/shared-config-updater.md +0 -310
  72. package/plugins/flow/agents/shared-coverage-enforcer.md +0 -184
  73. package/plugins/flow/agents/shared-error-handler.md +0 -217
  74. package/plugins/flow/agents/shared-file-creator.md +0 -344
  75. package/plugins/flow/agents/shared-impl-orchestrator.md +0 -312
  76. package/plugins/flow/agents/shared-impl-reporter.md +0 -368
  77. package/plugins/flow/agents/shared-impl-teammate.md +0 -201
  78. package/plugins/flow/agents/shared-linear-subtask-iterator.md +0 -337
  79. package/plugins/flow/agents/shared-logic-implementer.md +0 -243
  80. package/plugins/flow/agents/shared-maia-api.md +0 -26
  81. package/plugins/flow/agents/shared-parallelization-analyzer.md +0 -343
  82. package/plugins/flow/agents/shared-performance-validator.md +0 -168
  83. package/plugins/flow/agents/shared-plan-perspective.md +0 -269
  84. package/plugins/flow/agents/shared-project-standardizer.md +0 -205
  85. package/plugins/flow/agents/shared-report-synthesizer.md +0 -188
  86. package/plugins/flow/agents/shared-review-teammate.md +0 -189
  87. package/plugins/flow/agents/shared-security-scanner.md +0 -186
  88. package/plugins/flow/agents/shared-style-enforcer.md +0 -230
  89. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +0 -188
  90. package/plugins/flow/agents/shared-tdd-developer.md +0 -350
  91. package/plugins/flow/agents/shared-team-coordinator.md +0 -189
  92. package/plugins/flow/agents/shared-test-fixer.md +0 -186
  93. package/plugins/flow/agents/shared-test-runner.md +0 -191
  94. package/plugins/flow/agents/shared-ui-classifier.md +0 -263
  95. package/plugins/flow/agents/shared-verification-orchestrator.md +0 -194
  96. package/plugins/flow/agents/shared-verification-runner.md +0 -140
  97. package/plugins/flow/agents/ui-a11y-validator.md +0 -305
  98. package/plugins/flow/agents/ui-screenshot-reporter.md +0 -329
  99. package/plugins/flow/agents/ui-web-designer.md +0 -214
  100. package/plugins/flow/scripts/compute-session-tokens.sh +0 -39
  101. package/plugins/flow/skills/a11y-audit/SKILL.md +0 -214
  102. package/plugins/flow/skills/angular-patterns/SKILL.md +0 -191
  103. package/plugins/flow/skills/browser-capture/SKILL.md +0 -238
  104. package/plugins/flow/skills/commit/SKILL.md +0 -259
  105. package/plugins/flow/skills/debug-helper/SKILL.md +0 -375
  106. package/plugins/flow/skills/impl/SKILL.md +0 -992
  107. package/plugins/flow/skills/linear-suggestion/SKILL.md +0 -132
  108. package/plugins/flow/skills/maia-files-delete/SKILL.md +0 -59
  109. package/plugins/flow/skills/maia-files-upload/SKILL.md +0 -57
  110. package/plugins/flow/skills/nx-conventions/SKILL.md +0 -326
  111. package/plugins/flow/skills/plan/SKILL.md +0 -1033
  112. package/plugins/flow/skills/push/SKILL.md +0 -759
  113. package/plugins/flow/skills/review/SKILL.md +0 -443
  114. package/plugins/flow/skills/test-e2e/SKILL.md +0 -161
  115. package/plugins/flow/skills/test-unit/SKILL.md +0 -456
  116. package/plugins/flow-external/.claude-plugin/README.md +0 -152
  117. package/plugins/flow-external/.claude-plugin/merge-permissions.js +0 -80
  118. package/plugins/flow-external/.claude-plugin/plugin.json +0 -5
  119. package/plugins/flow-external/.claude-plugin/settings.template.json +0 -78
  120. package/plugins/flow-external/agents/angular-component-scaffolder.md +0 -269
  121. package/plugins/flow-external/agents/angular-directive-builder.md +0 -130
  122. package/plugins/flow-external/agents/angular-guard-builder.md +0 -70
  123. package/plugins/flow-external/agents/angular-pipe-builder.md +0 -82
  124. package/plugins/flow-external/agents/angular-resolver-builder.md +0 -74
  125. package/plugins/flow-external/agents/angular-service-builder.md +0 -160
  126. package/plugins/flow-external/agents/angular-state-builder.md +0 -254
  127. package/plugins/flow-external/agents/shared-build-verifier.md +0 -67
  128. package/plugins/flow-external/agents/shared-impl-orchestrator.md +0 -88
  129. package/plugins/flow-external/agents/shared-impl-reporter.md +0 -135
  130. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +0 -70
  131. package/plugins/flow-external/agents/shared-ui-classifier.md +0 -38
  132. package/plugins/flow-external/agents/ui-web-designer.md +0 -179
  133. package/plugins/flow-external/scripts/compute-session-tokens.sh +0 -39
  134. package/plugins/flow-external/skills/a11y-audit/SKILL.md +0 -96
  135. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +0 -267
  136. package/plugins/flow-external/skills/angular-patterns/SKILL.md +0 -170
  137. package/plugins/flow-external/skills/browser-capture/SKILL.md +0 -68
  138. package/plugins/flow-external/skills/commit/SKILL.md +0 -114
  139. package/plugins/flow-external/skills/debug-helper/SKILL.md +0 -131
  140. package/plugins/flow-external/skills/impl/SKILL.md +0 -217
  141. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +0 -62
  142. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +0 -34
  143. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +0 -41
  144. package/plugins/flow-external/skills/plan/SKILL.md +0 -334
  145. package/plugins/flow-external/skills/push/SKILL.md +0 -232
  146. package/plugins/flow-legacy/.claude-plugin/README.md +0 -143
  147. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +0 -94
  148. package/plugins/flow-legacy/.claude-plugin/plugin.json +0 -5
  149. package/plugins/flow-legacy/.claude-plugin/settings.template.json +0 -79
  150. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +0 -323
  151. package/plugins/flow-legacy/agents/angular-directive-builder.md +0 -258
  152. package/plugins/flow-legacy/agents/angular-guard-builder.md +0 -322
  153. package/plugins/flow-legacy/agents/angular-pipe-builder.md +0 -227
  154. package/plugins/flow-legacy/agents/angular-resolver-builder.md +0 -332
  155. package/plugins/flow-legacy/agents/angular-service-builder.md +0 -271
  156. package/plugins/flow-legacy/agents/angular-state-builder.md +0 -479
  157. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +0 -174
  158. package/plugins/flow-legacy/agents/shared-impl-reporter.md +0 -232
  159. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +0 -187
  160. package/plugins/flow-legacy/agents/shared-tdd-developer.md +0 -306
  161. package/plugins/flow-legacy/agents/shared-test-runner.md +0 -131
  162. package/plugins/flow-legacy/agents/shared-ui-classifier.md +0 -145
  163. package/plugins/flow-legacy/scripts/compute-session-tokens.sh +0 -39
  164. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +0 -214
  165. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +0 -346
  166. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +0 -238
  167. package/plugins/flow-legacy/skills/commit/SKILL.md +0 -215
  168. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +0 -395
  169. package/plugins/flow-legacy/skills/impl/SKILL.md +0 -710
  170. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +0 -132
  171. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +0 -59
  172. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +0 -57
  173. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +0 -368
  174. package/plugins/flow-legacy/skills/plan/SKILL.md +0 -742
  175. package/plugins/flow-legacy/skills/push/SKILL.md +0 -645
  176. package/plugins/flow-legacy/skills/test-unit/SKILL.md +0 -500
@@ -0,0 +1,164 @@
1
+ # libs/museum-<name> — structure to create
2
+
3
+ Copy from an existing article module in the reference MobilEMS app and substitute the module's
4
+ `<name>` / `<entity>`, threading `<PREFIX>`. The library has two projects: a
5
+ thin `domain` (one entity extending the npm `Article`) and a `shell/angular` (the Angular module +
6
+ list/item pages + service). Article modules use the npm `Article` entity directly through
7
+ `ArticlesSharedModule.forFeature`; the local domain entity is a near-empty subclass.
8
+
9
+ ```
10
+ libs/museum-<name>/
11
+ ├── domain/ # project: museum-<name>-domain
12
+ │ └── src/
13
+ │ ├── index.ts # export * from './lib/entities';
14
+ │ └── lib/
15
+ │ ├── entities/ # Museum<Name> extends Article (+ index)
16
+ │ ├── enums/ # .gitkeep
17
+ │ ├── specifications/ # .gitkeep
18
+ │ └── value-objects/ # .gitkeep
19
+ └── shell/angular/ # project: museum-<name>-shell-angular
20
+ └── src/
21
+ ├── index.ts # public barrel (pages + module [+ service])
22
+ └── lib/
23
+ ├── <name>.module.ts # Museum<Name>Module (references/module-and-routes.md)
24
+ ├── <name>.routes.ts
25
+ ├── index.ts # SERVICES const + barrel (see below)
26
+ ├── +state/ # ONLY if the module keeps feature state: <name>.reducer.ts
27
+ ├── pages/ # list (ListComponent), item (ItemComponent) + index (PAGES)
28
+ └── services/ # optional module service (e.g. a visit logger)
29
+ ```
30
+
31
+ ## Domain entity (thin subclass of the npm `Article`)
32
+
33
+ `domain/src/lib/entities/museum-<name>.entity.ts`:
34
+
35
+ ```ts
36
+ import { Model } from '@smartsoft001/models';
37
+ import { Article } from '@smartsoft001-mobilems/articles-domain';
38
+
39
+ @Model({})
40
+ export class Museum<Name> extends Article {}
41
+ ```
42
+
43
+ Then `entities/index.ts` re-exports it and `domain/src/index.ts` does `export * from './lib/entities';`.
44
+ (If the module needs extra fields, add them to this subclass.)
45
+
46
+ ## shell `lib/index.ts` — `SERVICES` + barrel
47
+
48
+ Define a `SERVICES` const here binding `ArticlesService` as the `CrudService`; a module that keeps
49
+ feature state spreads it into its providers:
50
+
51
+ ```ts
52
+ import { CrudService } from '@smartsoft001/crud-shell-angular';
53
+ import { ArticlesService } from '@smartsoft001-mobilems/articles-shell-angular';
54
+
55
+ export * from './pages/index';
56
+ export * from './<name>.module';
57
+
58
+ export const SERVICES = [
59
+ ArticlesService,
60
+ { provide: CrudService, useClass: ArticlesService },
61
+ ];
62
+ ```
63
+
64
+ ## shell `src/index.ts` (public barrel)
65
+
66
+ `export * from './lib/pages';` + `export * from './lib/<name>.module';` (plus the module's own service
67
+ if it ships one — see below).
68
+
69
+ ## `pages/index.ts`
70
+
71
+ ```ts
72
+ import { ItemComponent } from './item/item.component';
73
+ import { ListComponent } from './list/list.component';
74
+
75
+ export * from './item/item.component';
76
+ export * from './list/list.component';
77
+
78
+ export const PAGES = [ListComponent, ItemComponent];
79
+ ```
80
+
81
+ Copy the `list/` and `item/` `.component.ts` + `.html` from a reference article module, threading
82
+ `<PREFIX>`.
83
+
84
+ ## Optional: `+state/<name>.reducer.ts` (feature-local ngrx state)
85
+
86
+ Build this only if the module keeps its own ngrx state (Step 1 "feature state? = yes"). It wraps the
87
+ smart CRUD reducer keyed by the module's `<entity>`:
88
+
89
+ ```ts
90
+ import { Action } from '@ngrx/store';
91
+ import {
92
+ State as SmartState,
93
+ initialState as smartInitialState,
94
+ getReducer as smartGetReducer,
95
+ } from '@smartsoft001/crud-shell-angular';
96
+ import { Article } from '@smartsoft001-mobilems/articles-domain';
97
+
98
+ export type State = SmartState<Article>;
99
+
100
+ export const initialState = { ...smartInitialState };
101
+
102
+ const reducer = (state = initialState, action: any) => {
103
+ switch (action.type) {
104
+ default:
105
+ return smartGetReducer('<entity>')(state, action);
106
+ }
107
+ };
108
+
109
+ export function getReducer() {
110
+ return (state: any, action: Action) => reducer(state, action);
111
+ }
112
+ ```
113
+
114
+ The module then passes `reducerFactory: getReducer` to `forFeature` (see
115
+ `references/module-and-routes.md`). A module without feature state omits `+state/` entirely.
116
+
117
+ ## Optional: a module service
118
+
119
+ A module may ship a small injectable (for example, a visit logger). Copy it from the reference module
120
+ if it has one, threading `<PREFIX>`, and export it from `src/index.ts`:
121
+
122
+ ```ts
123
+ import { HttpClient } from '@angular/common/http';
124
+ import { inject, Injectable } from '@angular/core';
125
+ import { firstValueFrom } from 'rxjs';
126
+
127
+ import { environment } from '@<PREFIX>/angular';
128
+
129
+ @Injectable({ providedIn: 'root' })
130
+ export class Museum<Name>Service {
131
+ private http = inject(HttpClient);
132
+
133
+ logVisit(id: string | number): Promise<void> {
134
+ const url = environment.apiUrl + 'api/article/' + id + '/visit';
135
+ return firstValueFrom(this.http.post<void>(url, {}));
136
+ }
137
+ }
138
+ ```
139
+
140
+ > **Watch for cross-module service imports.** In the reference, some article modules' pages inject
141
+ > _another_ article module's service (e.g. a `news` page importing `MuseumArticlesService` from
142
+ > `@<ref-prefix>/museum-articles/shell/angular`). A generic article module must be self-contained — when
143
+ > a copied page injects a sibling module's service, give this module its **own** `Museum<Name>Service`
144
+ > (the template above) and rewire the page's import to it, rather than depending on a module that may
145
+ > not exist in the target.
146
+
147
+ ## Wiring
148
+
149
+ - **tsconfig.base.json paths** (add both):
150
+ ```json
151
+ "@<PREFIX>/museum-<name>/domain": ["libs/museum-<name>/domain/src/index.ts"],
152
+ "@<PREFIX>/museum-<name>/shell/angular": ["libs/museum-<name>/shell/angular/src/index.ts"]
153
+ ```
154
+ - **project.json / build config** — copy each project's build config and normalize every path field
155
+ the reference baked to its origin location — `sourceRoot`, `dest`, `outputPath`, `coverageDirectory`,
156
+ `jestConfig`, `lintFilePatterns`, and the jest `displayName` — to `libs/museum-<name>/...`. Some reference modules carry
157
+ stale values (e.g. a `sourceRoot` missing the `shell/angular` segment, or a `coverageDirectory`
158
+ under `packages/...`) while others are already correct — verify each against a known-good sibling and
159
+ fix only the stale ones. Set each `package.json` `name` to match (`museum-<name>-domain` /
160
+ `museum-<name>-shell-angular`) — a copied `package.json` may carry a stale name. A `domain` with no
161
+ `project.json` (Nx-inferred) is fine.
162
+ - **commit scope** — `commitlint.config.js` reads `libs/` dir names, so `museum-<name>` becomes a valid
163
+ scope automatically; no edit needed.
164
+ - **jest** — keep the reference `jest.config.ts` / `tsconfig.spec.json` so the shell unit-tests run.
@@ -0,0 +1,146 @@
1
+ # `Museum<Name>Module` + route registration
2
+
3
+ An article module wraps `ArticlesSharedModule.forFeature` over the npm `Article` entity and filters
4
+ its API requests with a `template` value. Thread `<PREFIX>` (the `environment` import) and the chosen
5
+ `<name>` / `<entity>` / `<template>`. The `Masonry` factory returns the real library in the browser
6
+ and a no-op mock during SSR. Copy the file structure from an existing article module in the reference
7
+ MobilEMS app and substitute the parameters.
8
+
9
+ ## `libs/museum-<name>/shell/angular/src/lib/<name>.module.ts`
10
+
11
+ ```ts
12
+ import { NgModule } from '@angular/core';
13
+ import { FormsModule } from '@angular/forms';
14
+ import { RouterModule } from '@angular/router';
15
+ import { SharedModule as SmartSharedModule } from '@smartsoft001/angular';
16
+ import { Article } from '@smartsoft001-mobilems/articles-domain';
17
+ import { ArticlesSharedModule } from '@smartsoft001-mobilems/articles-shell-angular';
18
+ import { Masonry } from '@thisissoon/angular-masonry';
19
+
20
+ import { environment } from '@<PREFIX>/angular';
21
+
22
+ import { routes } from './<name>.routes';
23
+
24
+ @NgModule({
25
+ providers: [
26
+ {
27
+ provide: Masonry,
28
+ useFactory: () => {
29
+ if (typeof window !== 'undefined' && (window as any)['Masonry']) {
30
+ return (window as any)['Masonry'];
31
+ }
32
+ // Return a mock for SSR
33
+ return class {
34
+ constructor() {
35
+ // no-op
36
+ }
37
+ layout() { return; }
38
+ reloadItems() { return; }
39
+ destroy() { return; }
40
+ };
41
+ },
42
+ },
43
+ ],
44
+ imports: [
45
+ FormsModule,
46
+ SmartSharedModule,
47
+ ArticlesSharedModule.forFeature({
48
+ routing: false,
49
+ config: {
50
+ type: Article,
51
+ apiUrl: environment.apiUrl,
52
+ entity: '<entity>',
53
+ baseQuery: [
54
+ { value: '<template>', key: 'template', type: '=', hidden: true },
55
+ ],
56
+ },
57
+ }),
58
+ RouterModule.forChild(routes),
59
+ ],
60
+ })
61
+ export class Museum<Name>Module {}
62
+ ```
63
+
64
+ The **`baseQuery`** is what scopes the module to its content: `key` is always `'template'`, `type` is
65
+ `'='`, `hidden` is `true`, and `value` is the module's `<template>` (the API then returns only records
66
+ matching that template). Change only the `value` between modules.
67
+
68
+ ### Optional: feature-local ngrx state
69
+
70
+ If the module keeps its own ngrx state, build `+state/<name>.reducer.ts` (see
71
+ `references/lib-contents.md`) exporting a `getReducer`, then in the module:
72
+
73
+ - pass `reducerFactory: getReducer` inside the `forFeature` `config`,
74
+ - define a `SERVICES` const in `lib/index.ts` that binds `ArticlesService` as the `CrudService`, and
75
+ spread it into the `providers` (alongside the `Masonry` provider).
76
+
77
+ (In the reference, the stateful article module also omits `SmartSharedModule` from its `imports` and
78
+ imports `ConfigsModule` from `@<PREFIX>/angular` — mirror whichever the reference module you copy
79
+ uses.) A module with no feature state omits `+state/` and the `reducerFactory` entirely.
80
+
81
+ ## `<name>.routes.ts`
82
+
83
+ ```ts
84
+ import { Route } from '@angular/router';
85
+
86
+ import { ItemComponent, ListComponent } from './pages';
87
+
88
+ export const routes: Route[] = [
89
+ { path: ':id/:slug', component: ItemComponent },
90
+ { path: ':id', component: ItemComponent },
91
+ { path: '', component: ListComponent },
92
+ ];
93
+ ```
94
+
95
+ ## Register in `apps/web/src/app/app.routes.ts`
96
+
97
+ Add the module's `<route>` to the `appRoutes` array (idempotently — if a `<route>` route already
98
+ exists, skip). Add it as a top-level route, and — if the module's results belong in site search — as a
99
+ child of the `wyszukaj/:text` route so `/wyszukaj/:text/<route>` works.
100
+
101
+ Top-level — add to `appRoutes`:
102
+
103
+ ```ts
104
+ {
105
+ path: '<route>',
106
+ loadChildren: () =>
107
+ import('@<PREFIX>/museum-<name>/shell/angular').then(
108
+ (m) => m.Museum<Name>Module,
109
+ ),
110
+ },
111
+ ```
112
+
113
+ Search child — add to the `children` of the `wyszukaj/:text` route, before the
114
+ `{ path: '', redirectTo: ... }` default:
115
+
116
+ ```ts
117
+ {
118
+ path: '<route>',
119
+ loadChildren: () =>
120
+ import('@<PREFIX>/museum-<name>/shell/angular').then(
121
+ (m) => m.Museum<Name>Module,
122
+ ),
123
+ },
124
+ ```
125
+
126
+ ## The `/article-preview` page (build once)
127
+
128
+ The app's content-preview page (`apps/web/src/app/article-preview/`) renders an `Article` for CMS
129
+ preview mode, so it imports `@smartsoft001-mobilems/articles-domain` and belongs to the articles
130
+ feature — the foundation deliberately leaves it out. Build it the first time an article module is
131
+ added, and skip it if it already exists (idempotent across article-module runs):
132
+
133
+ 1. Copy `apps/web/src/app/article-preview/` (`.component.ts` + `.html`) from the reference app, thread
134
+ `<PREFIX>`.
135
+ 2. Add its route to `appRoutes` in `apps/web/src/app/app.routes.ts` (a plain top-level route, before
136
+ the `**` catch-all):
137
+
138
+ ```ts
139
+ {
140
+ path: 'article-preview',
141
+ loadComponent: () =>
142
+ import('./article-preview/article-preview.component').then(
143
+ (m) => m.ArticlePreviewComponent,
144
+ ),
145
+ },
146
+ ```
@@ -0,0 +1,56 @@
1
+ # Article module shared components
2
+
3
+ An article module renders its records as cards in the grid view and rows in the list view, so it
4
+ contributes a pair of shared components to `libs/shared/angular` named after the module. Build them by
5
+ copying the card components of an existing article module in the reference MobilEMS app and adapting
6
+ them to the module's `<name>` and `<PREFIX>`. Every step is idempotent — if the target already exists,
7
+ leave it.
8
+
9
+ All paths below are under `libs/shared/angular/src/lib`.
10
+
11
+ ## Article card components — build + export
12
+
13
+ Build these two component directories and export them from `components/index.ts`:
14
+
15
+ | Component | Renders |
16
+ | ----------------------------- | -------------------------------- |
17
+ | `components/<name>-grid-item` | an article card in the grid view |
18
+ | `components/<name>-list-item` | an article row in the list view |
19
+
20
+ ```ts
21
+ // components/index.ts — these exports belong to the <name> module:
22
+ export * from './<name>-grid-item';
23
+ export * from './<name>-list-item';
24
+ ```
25
+
26
+ These render an `Article` (via the foundation's generic `IArticle` model), so they depend on
27
+ `@smartsoft001-mobilems/articles-domain` — which this skill installs. There is no module-specific
28
+ model type to add (contrast `mobilems-objects`, which adds `ISpecificObject` to `objects.model.ts`).
29
+
30
+ ## Optional: article gallery widget
31
+
32
+ If the project renders **article-gallery content blocks** (a page widget that embeds a gallery of
33
+ articles), build the article gallery widget once and register it in the widget content-type map. This
34
+ is shared by all article modules — build it the first time an article module needs it, and skip if a
35
+ previous article module already added it.
36
+
37
+ ```ts
38
+ // components/widget/index.ts:
39
+ export * from './gallery-article/widget-gallery-article.component';
40
+ ```
41
+
42
+ Register it in the widget content-type map in `components/widget/widget.component.ts`:
43
+
44
+ ```ts
45
+ import { WidgetGalleryArticleComponent } from './gallery-article/widget-gallery-article.component';
46
+ // …in the ArticleWidgetType → component map:
47
+ [ArticleWidgetType.GALLERY_ARTICLE]: WidgetGalleryArticleComponent,
48
+ ```
49
+
50
+ The widget container renders sub-widgets via `NgComponentOutlet`, so the gallery widget goes in the
51
+ type-map only — it does **not** go in the container's `imports` array.
52
+
53
+ ## Verify
54
+
55
+ `scripts/verify-module.sh <workspace> <PREFIX> <name>` checks the module's `<name>-grid-item` and
56
+ `<name>-list-item` exist and are exported from the components barrel.
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # detect-init.sh <workspace-root>
4
+ #
5
+ # Precondition gate for mobilems-objects (and the other module skills follow the same shape):
6
+ # confirm the MobilEMS foundation from mobilems-project-init is present.
7
+ #
8
+ # Exit 0 → foundation present, OK to add the module.
9
+ # Exit 3 → foundation missing (tell the user to run /mobilems:project-init first).
10
+ set -eu
11
+
12
+ ROOT="${1:?usage: detect-init.sh <workspace-root>}"
13
+ cd "$ROOT" 2>/dev/null || { echo "ERROR: no such dir: $ROOT" >&2; exit 2; }
14
+
15
+ miss() {
16
+ echo "FOUNDATION MISSING: $1" >&2
17
+ echo "Run /mobilems:project-init first to lay down the MobilEMS foundation." >&2
18
+ exit 3
19
+ }
20
+
21
+ [ -f apps/web/src/app/app.config.ts ] || miss "app.config.ts missing"
22
+ grep -q "SharedModule.forRoot" apps/web/src/app/app.config.ts || miss "SharedModule.forRoot not in app.config.ts (foundation not applied)"
23
+ grep -q "./lib/components" libs/shared/angular/src/index.ts 2>/dev/null || miss "shared-lib components barrel not populated"
24
+ [ -f apps/web/src/app/app.routes.ts ] || miss "app.routes.ts missing"
25
+
26
+ PREFIX="$(grep -oE '@[a-z0-9-]+/angular' tsconfig.base.json | head -1 | sed -E 's#@([a-z0-9-]+)/angular#\1#')"
27
+ echo "FOUNDATION OK. Detected prefix: ${PREFIX:-<unknown>}"
28
+ [ -d libs/museum-objects ] && echo "NOTE: libs/museum-objects already exists — build steps must be idempotent." >&2
29
+ exit 0
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # verify-module.sh <workspace-root> <PREFIX> <name> [template]
4
+ #
5
+ # Post-condition check for one article module named <name>: library created, ArticlesSharedModule
6
+ # .forFeature wired (with the template value if given), route registered, and the module's article
7
+ # card shared components built + exported.
8
+ set -eu
9
+
10
+ ROOT="${1:?usage: verify-module.sh <workspace-root> <PREFIX> <name> [template]}"
11
+ PREFIX="${2:?usage: verify-module.sh <workspace-root> <PREFIX> <name> [template]}"
12
+ NAME="${3:?usage: verify-module.sh <workspace-root> <PREFIX> <name> [template]}"
13
+ TEMPLATE="${4:-}"
14
+ cd "$ROOT" 2>/dev/null || { echo "ERROR: no such dir: $ROOT" >&2; exit 2; }
15
+
16
+ LIBF="museum-$NAME"
17
+ fail=0
18
+ pass() { echo " PASS: $1"; }
19
+ bad() { echo " FAIL: $1" >&2; fail=1; }
20
+ info() { echo " INFO: $1"; }
21
+
22
+ echo "== Verifying article module: name=$NAME lib=$LIBF =="
23
+
24
+ echo "== Library =="
25
+ MOD="$(ls libs/$LIBF/shell/angular/src/lib/*.module.ts 2>/dev/null | head -1)"
26
+ [ -n "$MOD" ] && pass "module file present ($MOD)" || bad "no *.module.ts in libs/$LIBF/shell/angular/src/lib"
27
+ [ -f "libs/$LIBF/domain/src/lib/entities/index.ts" ] && pass "domain entity present" || bad "domain entity missing"
28
+ grep -q "$LIBF/shell/angular" tsconfig.base.json && pass "tsconfig shell path added" || bad "tsconfig.base.json shell path missing"
29
+ grep -q "$LIBF/domain" tsconfig.base.json && pass "tsconfig domain path added" || bad "tsconfig.base.json domain path missing"
30
+
31
+ echo "== forFeature wiring =="
32
+ if [ -n "$MOD" ]; then
33
+ grep -q "ArticlesSharedModule.forFeature" "$MOD" && pass "ArticlesSharedModule.forFeature wired" || bad "ArticlesSharedModule.forFeature missing"
34
+ grep -q "key: 'template'" "$MOD" && pass "baseQuery filters on key 'template'" || bad "baseQuery key 'template' missing"
35
+ if [ -n "$TEMPLATE" ]; then
36
+ grep -q "$TEMPLATE" "$MOD" && pass "template value '$TEMPLATE' present" || bad "template value '$TEMPLATE' missing"
37
+ fi
38
+ grep -q "reducerFactory" "$MOD" && info "module keeps feature state (reducerFactory present)" || info "module has no feature state"
39
+ fi
40
+
41
+ echo "== Route registration =="
42
+ ROUTES=apps/web/src/app/app.routes.ts
43
+ n=$(grep -c "$LIBF/shell/angular" "$ROUTES" 2>/dev/null || true)
44
+ [ "${n:-0}" -ge 1 ] && pass "route registered ($n occurrence(s) — top-level$([ "${n:-0}" -ge 2 ] && echo ' + search child'))" || bad "route not in app.routes.ts"
45
+
46
+ echo "== Article card shared components =="
47
+ COMP=libs/shared/angular/src/lib/components
48
+ for d in "$NAME-grid-item" "$NAME-list-item"; do
49
+ [ -d "$COMP/$d" ] && pass "built $d" || bad "missing $COMP/$d"
50
+ done
51
+ grep -q "$NAME-grid-item" "$COMP/index.ts" && pass "$NAME-grid-item exported" || bad "$NAME-grid-item export missing"
52
+ grep -q "$NAME-list-item" "$COMP/index.ts" && pass "$NAME-list-item exported" || bad "$NAME-list-item export missing"
53
+
54
+ echo "== Deps =="
55
+ for p in articles-domain articles-shell-angular articles-shell-dtos; do
56
+ grep -q "@smartsoft001-mobilems/$p" package.json && pass "$p dep" || bad "$p dep missing"
57
+ done
58
+
59
+ echo
60
+ if [ "$fail" = 0 ]; then echo "VERIFY: all checks passed."; else echo "VERIFY: FAILED — fix the items above and re-run." >&2; fi
61
+ exit "$fail"
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: mobilems-docs-reader
3
+ description: Answer questions about the MuzaCMS / MobileMS indexer API by reading a freshly-fetched OpenAPI spec. Use whenever the user asks about endpoints, request/response shapes, status codes, auth, or behavior of the indexer API (host develop-indexer-api.mobilems.pl). Read-only — never fabricates endpoints.
4
+ allowed-tools:
5
+ - Bash
6
+ - Read
7
+ - Glob
8
+ - Grep
9
+ ---
10
+
11
+ You answer questions about the **MuzaCMS / MobileMS indexer API** strictly from the OpenAPI (Swagger 2.0) specification. You never invent endpoints, schemas, or status codes — if it is not in the spec, you say so plainly.
12
+
13
+ The spec is **not bundled**. It is fetched from the live MuzaCMS instance by a refresh script that lives next to this skill, using credentials supplied via environment variables. The script caches the fetched spec per Claude Code session (with an 8-hour TTL safety net), so it may skip the actual network call and reuse a cached copy on follow-up invocations within the same session.
14
+
15
+ ## Step 1 — Run the refresh script (mandatory)
16
+
17
+ On every invocation, run the refresh script via Bash. The script itself decides whether to actually fetch — it owns the cache. Your job is only to run it and react to the result. A successful run may be either:
18
+
19
+ - A real fetch (`Refreshing MuzaCMS API spec from ... → GET /admin/login → POST /admin/login → GET /docs/api → ✓ Refreshed N bytes ...`), or
20
+ - A cache hit (`✓ spec cached for this Claude Code session (refreshed N min ago at ...), skipping fetch`).
21
+
22
+ Both are exit-code-0 successes. Treat them identically and proceed to Step 2. **Do not** attempt to bypass the cache, delete the cache file, or force a refetch — the cache is intentional and the script's decision is authoritative.
23
+
24
+ ### Invocation
25
+
26
+ The refresh script is shipped under `plugins/mobilems/scripts/`. Invoke it through `bash` so the executable bit is irrelevant:
27
+
28
+ ```
29
+ bash ./node_modules/@smartsoft001-mobilems/claude-plugins/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh --quiet
30
+ ```
31
+
32
+ Outcomes:
33
+
34
+ - **Success (exit 0)** → jump to Step 2.
35
+ - **Script-level error** (missing env vars, missing tooling, auth rejected, HTTP error, parse failure, etc.) → jump to the matching Fail mode below.
36
+ - **Permission denied by Claude Code** → jump to "Fail mode — permission denied".
37
+
38
+ The script reads two environment variables — `MOBILEMS_LOGIN` and `MOBILEMS_PASSWORD` — performs the Symfony CSRF + session login against `https://develop-indexer.mobilems.pl`, fetches `/docs/api`, and writes the spec to `shared-assets/mobilems-api.json` inside the installed package. It also auto-loads `.env` from the current working directory; no shell sourcing is needed.
39
+
40
+ ### Fail mode — permission denied by Claude Code
41
+
42
+ If the Bash call is rejected by Claude Code's permission system, stop and tell the user verbatim:
43
+
44
+ > The MuzaCMS spec could not be refreshed because Claude Code denied permission to run the refresh script. To allow it, add this entry to your project's `.claude/settings.json` (committed) or `.claude/settings.local.json` (per-dev, gitignored) under `permissions.allow`, then ask again:
45
+ >
46
+ > - `"Bash(bash ./node_modules/@smartsoft001-mobilems/claude-plugins/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh:*)"`
47
+
48
+ Do not attempt to answer the user's question from training knowledge. Do not invent alternative invocation patterns to try to bypass the denial.
49
+
50
+ ### Fail mode — missing env vars
51
+
52
+ If the script exits non-zero with a message starting `✗ Brak wymaganych zmiennych środowiskowych` (or English equivalent listing `MOBILEMS_LOGIN` / `MOBILEMS_PASSWORD`), **stop immediately**. Relay the script's message verbatim to the user.
53
+
54
+ Do not attempt to answer the user's question from training knowledge. Do not guess. Do not read any pre-existing `mobilems-api.json` that may be lying around in `node_modules/` — without a successful refresh you have no confirmation it is current.
55
+
56
+ ### Fail mode — missing tooling
57
+
58
+ If the script exits with a message about missing `curl` or `jq`, relay it verbatim. The script tells the user exactly how to install the missing dependency (`brew install jq` / `apt install jq`).
59
+
60
+ ### Fail mode — other script failures
61
+
62
+ If the script fails for any other reason (HTTP error, auth rejected, parse failure), report the exact error message from the script back to the user and stop. Do not answer the API question.
63
+
64
+ ## Step 2 — Locate the freshly-written spec
65
+
66
+ Use `Glob` with this pattern:
67
+
68
+ ```
69
+ **/claude-plugins/**/shared-assets/mobilems-api.json
70
+ ```
71
+
72
+ The hit lives under `node_modules/@smartsoft001-mobilems/claude-plugins/shared-assets/` after a successful refresh. Exclude `dist/` and `tmp/` from the Glob, but **do** allow `node_modules/`.
73
+
74
+ If the Glob returns nothing after the refresh script reported success, something is wrong with the install layout — tell the user and stop.
75
+
76
+ ## Step 3 — Answer from the spec
77
+
78
+ The spec is **Swagger 2.0** with this wrapping shape:
79
+
80
+ ```
81
+ { "spec": { "swagger": "2.0", "paths": {...}, "definitions": {...} } }
82
+ ```
83
+
84
+ Always traverse into `.spec` first.
85
+
86
+ When the user asks about endpoints:
87
+
88
+ 1. **Locate the path** in `spec.paths`. Look for the exact path the user mentioned, including any path parameters (`{id}`).
89
+ 2. **Quote the HTTP method(s) and path verbatim.** Example: `GET /api/objects/{id}`.
90
+ 3. For request bodies and responses, cite the `$ref` target by name and (briefly) summarize its shape from `spec.definitions`.
91
+ 4. For status codes, list each documented response from `responses` with its `description`.
92
+ 5. For auth, check both the operation-level `security` and the global `spec.securityDefinitions`.
93
+
94
+ If the user asks about a path that is **not in the spec**, say so explicitly:
95
+
96
+ > The spec does not document a `DELETE /api/articles/{id}` endpoint. The articles paths in the spec are: `[list actual paths]`. If you've seen this endpoint elsewhere, it may exist in the running service without being documented — verify with a live request.
97
+
98
+ ## Known caveats — always surface when relevant
99
+
100
+ - **Response schemas occasionally diverge from runtime.** Documented response shapes have, in practice, not always matched what the live API actually returns. When the user is about to implement against a response schema, add a brief reminder to verify with a real request before relying on the documented shape.
101
+ - **Spec is regenerated server-side from PHP annotations.** Newly added endpoints in the live service may not appear until the next backend deployment, even with a fresh fetch.
102
+ - **Auth flow nuance:** the spec describes the indexer API itself; the `/admin/login` flow used by the refresh script is separate and not documented in the spec.
103
+
104
+ ## Answering style
105
+
106
+ - Be terse. The user wants a specific fact, not a tutorial on Swagger.
107
+ - Always include exact path + method + relevant status codes when applicable.
108
+ - When quoting definitions, use the schema name (e.g., `Object`, `Unauthorised`) as it appears in `spec.definitions`.
109
+ - If multiple endpoints match a vague question, list them — don't pick one arbitrarily.
110
+
111
+ ## When NOT to use this skill
112
+
113
+ - Non-MobileMS APIs (any other host).
114
+ - Generic REST/OpenAPI guidance unrelated to the indexer.
115
+ - Schema design decisions ("should I add X field?") — this skill only describes what exists.
116
+ - Anything requiring a live network call to the API itself.
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: mobilems-events
3
+ description: Add the museum EVENTS feature module (wydarzenia) to a MobilEMS app initialized with mobilems-project-init. Use whenever the user wants to add / scaffold / wire the events module, the "wydarzenia" pages (event list + event detail + booking/reservation flow with confirm + cancel), event booking, event reservation, an event calendar / available-dates picker, or asks to "dodaj moduł wydarzeń / rezerwacji wydarzeń". Creates libs/museum-events (shell/angular only — a standalone booking module), registers the /wydarzenia route, and confirms the foundation packages it reuses are present. 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 events module
9
+
10
+ Add the **events** (wydarzenia) feature module to a MobilEMS app whose foundation was built by
11
+ `mobilems-project-init`. Events is a self-contained booking / reservation system: a list of events,
12
+ an event detail page, and a reservation flow (booking form -> confirmation -> cancellation) driven by
13
+ its own `EventsReservationService` over the event / event-periods / event-reservations API. This
14
+ skill builds the `libs/museum-events` library and registers a single top-level `/wydarzenia` route.
15
+
16
+ Events has a leaner shape than the other feature modules: a pure `RouterModule.forChild` module with
17
+ **lazy `loadComponent` routes** and **no shared-module `forFeature`**, and it ships **only a
18
+ `shell/angular` project** (there is no `domain` library). All of its UI and data access live inside
19
+ its own `shell/angular`.
20
+
21
+ ## Precondition
22
+
23
+ Run `scripts/detect-init.sh <workspace-root>`. It confirms the MobilEMS foundation is present
24
+ (`SharedModule.forRoot` in `app.config.ts`, a populated shared-lib barrel). If not, tell the user to
25
+ run `/mobilems:project-init` first. Hold `<PREFIX>` (from `tsconfig.base.json`; the reference
26
+ MobilEMS app uses `@msr`) and the reference repo path (same one init used).
27
+
28
+ ## Steps
29
+
30
+ 1. **npm deps (precondition check)** — events imports only foundation packages:
31
+ `@smartsoft001-mobilems/angular`, `@smartsoft001-mobilems/models`, `@smartsoft001/angular`,
32
+ `@thisissoon/angular-masonry`, and `@ngx-translate/core` — all already installed by
33
+ `mobilems-project-init`. So this step is a CHECK: confirm those lines are in `package.json`; there
34
+ is nothing new to add. As a safeguard, grep the copied lib for any third-party import not in that
35
+ foundation set and add only what is genuinely missing. Do not `npm install` unless asked.
36
+ 2. **Library** — create `libs/museum-events/shell/angular` per `references/lib-contents.md`: copy the
37
+ shell (`MuseumEventsModule`, `events.routes.ts`, `pages/{list,item,booking,confirm,cancel}`,
38
+ `services/events-reservation.service.ts`, `models/events.models.ts`, `pipes/time-format.pipe.ts`,
39
+ and the `src/__mocks__/@smartsoft001-mobilems/{angular,models}.ts` jest mocks), thread `<PREFIX>`.
40
+ Add the single `tsconfig.base.json` path `@<PREFIX>/museum-events/shell/angular` and the
41
+ `museum-events` commit scope.
42
+ 3. **Module + routes** — see `references/module-and-routes.md`: `MuseumEventsModule` is just
43
+ `@NgModule({ imports: [RouterModule.forChild(eventsRoutes)] })`; `eventsRoutes` uses lazy
44
+ `loadComponent` for every page and provides the `Masonry` SSR factory on the list route. Add the
45
+ lazy `wydarzenia` route to the `appRoutes` array in `apps/web/src/app/app.routes.ts` as a single
46
+ top-level route.
47
+ 4. **Verify** — run `scripts/verify-module.sh <workspace-root> <PREFIX>`: asserts the
48
+ `libs/museum-events/shell/angular` lib exists with `MuseumEventsModule` (`RouterModule.forChild`)
49
+ and `events.routes.ts`, the `@<PREFIX>/museum-events/shell/angular` tsconfig path is added, the
50
+ five pages + `EventsReservationService` + `events.models.ts` + `TimeFormatPipe` are present, the
51
+ `wydarzenia` route is registered as a single top-level route, and the foundation deps it reuses are
52
+ in `package.json`. Fix and re-run.
53
+
54
+ ## Notes
55
+
56
+ - Events is a standalone booking module: it owns its data access (`EventsReservationService` calling
57
+ the events API) and contributes **nothing** to `libs/shared/angular`. The shared lib stays
58
+ untouched.
59
+ - Events ships **only** a `shell/angular` project — there is no `domain` library and no shared-module
60
+ `forFeature`; its event/reservation types live in `shell/angular/src/lib/models/events.models.ts`.
61
+ - `/wydarzenia` is a top-level route only. Events is a booking destination, not a search result, so it
62
+ is NOT added under the `wyszukaj/:text` search children.
63
+ - This skill ONLY touches the events module + its route. It never adds other feature modules, never
64
+ re-runs the foundation, and never edits `libs/shared/angular`.
65
+ - Bundled `references/` + `scripts/` ship automatically. Do not hand-edit `plugin.json`.