@smartsoft001-mobilems/claude-plugins 2.86.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.
- package/package.json +1 -1
- package/plugins/mobilems/.claude-plugin/plugin.json +1 -1
- package/plugins/mobilems/skills/mobilems-articles/SKILL.md +84 -0
- package/plugins/mobilems/skills/mobilems-articles/references/lib-contents.md +164 -0
- package/plugins/mobilems/skills/mobilems-articles/references/module-and-routes.md +146 -0
- package/plugins/mobilems/skills/mobilems-articles/references/shared-components.md +56 -0
- package/plugins/mobilems/skills/mobilems-articles/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-articles/scripts/verify-module.sh +61 -0
- package/plugins/mobilems/skills/mobilems-events/SKILL.md +65 -0
- package/plugins/mobilems/skills/mobilems-events/references/lib-contents.md +212 -0
- package/plugins/mobilems/skills/mobilems-events/references/module-and-routes.md +113 -0
- package/plugins/mobilems/skills/mobilems-events/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-events/scripts/verify-module.sh +59 -0
- package/plugins/mobilems/skills/mobilems-object-collections/SKILL.md +52 -0
- package/plugins/mobilems/skills/mobilems-object-collections/references/lib-contents.md +76 -0
- package/plugins/mobilems/skills/mobilems-object-collections/references/module-and-routes.md +116 -0
- package/plugins/mobilems/skills/mobilems-object-collections/references/shared-components.md +61 -0
- package/plugins/mobilems/skills/mobilems-object-collections/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-object-collections/scripts/verify-module.sh +44 -0
- package/plugins/mobilems/skills/mobilems-objects/SKILL.md +52 -0
- package/plugins/mobilems/skills/mobilems-objects/references/lib-contents.md +68 -0
- package/plugins/mobilems/skills/mobilems-objects/references/module-and-routes.md +108 -0
- package/plugins/mobilems/skills/mobilems-objects/references/shared-components.md +69 -0
- package/plugins/mobilems/skills/mobilems-objects/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-objects/scripts/verify-module.sh +51 -0
- package/plugins/mobilems/skills/mobilems-partners/SKILL.md +65 -0
- package/plugins/mobilems/skills/mobilems-partners/references/lib-contents.md +160 -0
- package/plugins/mobilems/skills/mobilems-partners/references/module-and-routes.md +125 -0
- package/plugins/mobilems/skills/mobilems-partners/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-partners/scripts/verify-module.sh +59 -0
- package/plugins/mobilems/skills/mobilems-project-init/SKILL.md +134 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/app-shell.md +107 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/claude-config.md +44 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/config-providers.md +203 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/npm-deps.md +66 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/server-env.md +89 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/shared-lib.md +125 -0
- package/plugins/mobilems/skills/mobilems-project-init/references/tailwind-styles.md +106 -0
- package/plugins/mobilems/skills/mobilems-project-init/scripts/classify-shared-components.py +114 -0
- package/plugins/mobilems/skills/mobilems-project-init/scripts/detect-base.sh +49 -0
- package/plugins/mobilems/skills/mobilems-project-init/scripts/verify-init.sh +73 -0
- package/plugins/mobilems/skills/mobilems-thematic-publications/SKILL.md +60 -0
- package/plugins/mobilems/skills/mobilems-thematic-publications/references/lib-contents.md +134 -0
- package/plugins/mobilems/skills/mobilems-thematic-publications/references/module-and-routes.md +107 -0
- package/plugins/mobilems/skills/mobilems-thematic-publications/scripts/detect-init.sh +29 -0
- package/plugins/mobilems/skills/mobilems-thematic-publications/scripts/verify-module.sh +56 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# libs/museum-partners — structure to create
|
|
2
|
+
|
|
3
|
+
Copy from the reference MobilEMS app's `libs/museum-partners` and thread `<PREFIX>`. The lib has two
|
|
4
|
+
projects: a `domain` (the entity) and a `shell/angular` (the Angular module + NgRx `+state` + UI).
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
libs/museum-partners/
|
|
8
|
+
├── domain/ # project: museum-partners-domain
|
|
9
|
+
│ ├── package.json # "name": "museum-partners-domain"
|
|
10
|
+
│ ├── jest.config.js # displayName + coverageDirectory under libs/museum-partners/domain
|
|
11
|
+
│ └── src/
|
|
12
|
+
│ ├── index.ts # export * from './lib/entities';
|
|
13
|
+
│ ├── features.ts # export const DOMAIN_SERVICES = [];
|
|
14
|
+
│ └── lib/
|
|
15
|
+
│ └── entities/ # museum-partner.entity.ts (MuseumPartner) + index
|
|
16
|
+
└── shell/angular/ # project: museum-partners-shell-angular
|
|
17
|
+
└── src/
|
|
18
|
+
├── index.ts # export * from './lib/pages'; export * from './lib/partners.module';
|
|
19
|
+
└── lib/
|
|
20
|
+
├── index.ts # export * from './pages'; './components'; './partners.module';
|
|
21
|
+
├── partners.module.ts # MuseumPartnersModule (references/module-and-routes.md)
|
|
22
|
+
├── partners.routes.ts
|
|
23
|
+
├── +state/ # partners.reducer.ts (getReducer)
|
|
24
|
+
├── components/ # grid-item (GridItemComponent), list-item (ListItemComponent) + index
|
|
25
|
+
├── pages/ # list (ListComponent), item (ItemComponent) + index
|
|
26
|
+
└── services/ # partners/partners.service.ts + index (SERVICES)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> The partner cards (`grid-item`, `list-item`) live in **this** lib, not in `libs/shared/angular`.
|
|
30
|
+
> Copy only what the reference has — there is no `+state/*.facade.ts`/`*.selectors.ts` and no
|
|
31
|
+
> `directives/` dir in this module; the only `+state` file is `partners.reducer.ts`.
|
|
32
|
+
|
|
33
|
+
## Domain entity (verbatim — thread nothing; pure types)
|
|
34
|
+
|
|
35
|
+
This entity `implements IEntity<string>` — it does NOT extend the Articles `Article` base class. It
|
|
36
|
+
pulls `MsFile` from `@smartsoft001-mobilems/models` and **`IMsObjectConnection` from
|
|
37
|
+
`@smartsoft001-mobilems/objects-domain`** (the cross-module type that drives the SKILL.md
|
|
38
|
+
objects-domain dep). Copy `domain/src/lib/entities/museum-partner.entity.ts` verbatim:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { IEntity } from '@smartsoft001/domain-core';
|
|
42
|
+
import { Model, Field } from '@smartsoft001/models';
|
|
43
|
+
import { MsFile } from '@smartsoft001-mobilems/models';
|
|
44
|
+
import { IMsObjectConnection } from '@smartsoft001-mobilems/objects-domain';
|
|
45
|
+
|
|
46
|
+
@Model({})
|
|
47
|
+
export class MuseumPartner implements IEntity<string> {
|
|
48
|
+
id!: string;
|
|
49
|
+
|
|
50
|
+
@Field()
|
|
51
|
+
name!: string;
|
|
52
|
+
|
|
53
|
+
@Field()
|
|
54
|
+
additionalInfo!: string;
|
|
55
|
+
|
|
56
|
+
@Field()
|
|
57
|
+
geoLocation!: any;
|
|
58
|
+
|
|
59
|
+
@Field()
|
|
60
|
+
latitude!: number;
|
|
61
|
+
|
|
62
|
+
@Field()
|
|
63
|
+
longitude!: number;
|
|
64
|
+
|
|
65
|
+
@Field()
|
|
66
|
+
objectCount!: number;
|
|
67
|
+
|
|
68
|
+
@Field()
|
|
69
|
+
extraData!: {
|
|
70
|
+
name: string;
|
|
71
|
+
phone: string;
|
|
72
|
+
emailAddress?: string;
|
|
73
|
+
description: string;
|
|
74
|
+
shortDescription: string;
|
|
75
|
+
address: string;
|
|
76
|
+
openingHours: number;
|
|
77
|
+
ticketPrices: number;
|
|
78
|
+
logo: MsFile;
|
|
79
|
+
image: MsFile;
|
|
80
|
+
website: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
@Field()
|
|
84
|
+
connections?: Array<IMsObjectConnection>;
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Shell `+state` (NgRx — copy verbatim, thread `<PREFIX>`)
|
|
89
|
+
|
|
90
|
+
- `partners.reducer.ts` exports `getReducer()` — wraps `@smartsoft001/crud-shell-angular`'s
|
|
91
|
+
`getReducer('partners')` and returns a `(state, action) => …` reducer. This is the function passed
|
|
92
|
+
as `reducerFactory` in the module config. The reducer's `State` type is `SmartState<Article>`
|
|
93
|
+
(from `@smartsoft001-mobilems/articles-domain`), since the module is configured over `Article`.
|
|
94
|
+
|
|
95
|
+
## Services — `services/index.ts` exports a `SERVICES` array (copy verbatim)
|
|
96
|
+
|
|
97
|
+
`PartnersService extends CrudBaseService<MuseumPartner>` (from `@smartsoft001-mobilems/angular`) and
|
|
98
|
+
points its list/detail URLs at the partners (`dictionary/Department`) endpoints, enriching list items
|
|
99
|
+
with geodata. It is bound to BOTH `CrudService` and `ArticlesService` (the reused Articles shared
|
|
100
|
+
module resolves `ArticlesService`):
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { CrudService } from '@smartsoft001/crud-shell-angular';
|
|
104
|
+
import { ArticlesService } from '@smartsoft001-mobilems/articles-shell-angular';
|
|
105
|
+
|
|
106
|
+
import { PartnersService } from './partners/partners.service';
|
|
107
|
+
|
|
108
|
+
export * from './partners/partners.service';
|
|
109
|
+
|
|
110
|
+
export const SERVICES = [
|
|
111
|
+
PartnersService,
|
|
112
|
+
{
|
|
113
|
+
provide: CrudService,
|
|
114
|
+
useClass: PartnersService,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
provide: ArticlesService,
|
|
118
|
+
useClass: PartnersService,
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## UI components & pages
|
|
124
|
+
|
|
125
|
+
- `components/grid-item` (`GridItemComponent`, selector `app-partners-grid-item`) and
|
|
126
|
+
`components/list-item` (`ListItemComponent`, selector `app-partners-list-item`) are the partner
|
|
127
|
+
cards used by the list page; `components/index.ts` re-exports both. Copy verbatim, thread
|
|
128
|
+
`<PREFIX>`.
|
|
129
|
+
- `pages/list` (`ListComponent extends ArticlesListComponent`) renders the sortable/paged masonry
|
|
130
|
+
grid; it uses `@debounce` from `lodash-decorators` (the SKILL.md dep) for its date filter.
|
|
131
|
+
- `pages/item` (`ItemComponent extends ArticlesItemComponent`) renders the partner detail with map
|
|
132
|
+
and connected objects (it composes foundation components from `@<PREFIX>/angular` such as
|
|
133
|
+
`MapComponent` and `ObjectsGridItemComponent`).
|
|
134
|
+
|
|
135
|
+
## Wiring
|
|
136
|
+
|
|
137
|
+
- **tsconfig.base.json paths** (add both):
|
|
138
|
+
```json
|
|
139
|
+
"@<PREFIX>/museum-partners/domain": ["libs/museum-partners/domain/src/index.ts"],
|
|
140
|
+
"@<PREFIX>/museum-partners/shell/angular": ["libs/museum-partners/shell/angular/src/index.ts"]
|
|
141
|
+
```
|
|
142
|
+
- **project.json / build config** — copy each project's config (names `museum-partners-domain`,
|
|
143
|
+
`museum-partners-shell-angular`) and normalize every path field the reference baked to its origin
|
|
144
|
+
location — `sourceRoot`, `dest`, `outputPath`, `coverageDirectory`, `jestConfig`,
|
|
145
|
+
`lintFilePatterns`, and the jest `displayName` — to `libs/museum-partners/...`. Some reference
|
|
146
|
+
fields are stale and need fixing: the shell `project.json` `sourceRoot` reads
|
|
147
|
+
`libs/museum-partners/src` (correct it to `libs/museum-partners/shell/angular/src`), and the shell
|
|
148
|
+
`jest.config.ts` `coverageDirectory` points at a sibling's `coverage/packages/...` path (correct it
|
|
149
|
+
to `coverage/libs/museum-partners/shell/angular`); the domain `package.json` `name` reads
|
|
150
|
+
`museum-objects-domain` (correct it to `museum-partners-domain`). Others are already correct (the
|
|
151
|
+
domain `jest.config.js` `displayName`/`coverageDirectory` are right) — verify each against a
|
|
152
|
+
known-good sibling and fix only the stale ones. A `domain` with no `project.json` (Nx-inferred) is
|
|
153
|
+
fine — just set its `package.json` `name`.
|
|
154
|
+
- **commit scope** — `commitlint.config.js` reads `libs/` dir names, so `museum-partners` becomes a
|
|
155
|
+
valid scope automatically; no edit needed.
|
|
156
|
+
|
|
157
|
+
This module reuses the Articles shared module, so it needs the three `@smartsoft001-mobilems/articles-*`
|
|
158
|
+
npm packages plus `@smartsoft001-mobilems/objects-domain` (for `IMsObjectConnection`) and
|
|
159
|
+
`lodash-decorators` (see SKILL.md step 1). `@angular/cdk`, `@thisissoon/angular-masonry`,
|
|
160
|
+
`@ngx-translate/core`, and `@smartsoft001-mobilems/{angular,models}` are already foundation deps.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# MuseumPartnersModule + route registration
|
|
2
|
+
|
|
3
|
+
## `libs/museum-partners/shell/angular/src/lib/partners.module.ts`
|
|
4
|
+
|
|
5
|
+
Thread `<PREFIX>` (the `environment` import). This module REUSES `ArticlesSharedModule` (the same
|
|
6
|
+
shared module the news/articles/thematic-paths modules use) but configures it over the Articles
|
|
7
|
+
`Article` type with its OWN `getReducer` and **no `baseQuery`**. The `Masonry` factory returns the
|
|
8
|
+
real library in the browser and a no-op mock during SSR (identical to objects). It provides the
|
|
9
|
+
`SERVICES` array (which binds both `CrudService` and `ArticlesService` to `PartnersService`).
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { NgModule } from '@angular/core';
|
|
13
|
+
import { FormsModule } from '@angular/forms';
|
|
14
|
+
import { RouterModule } from '@angular/router';
|
|
15
|
+
import { Article } from '@smartsoft001-mobilems/articles-domain';
|
|
16
|
+
import { ArticlesSharedModule } from '@smartsoft001-mobilems/articles-shell-angular';
|
|
17
|
+
import { Masonry } from '@thisissoon/angular-masonry';
|
|
18
|
+
|
|
19
|
+
import { environment } from '@<PREFIX>/angular';
|
|
20
|
+
|
|
21
|
+
import { getReducer } from './+state/partners.reducer';
|
|
22
|
+
import { routes } from './partners.routes';
|
|
23
|
+
import { SERVICES } from './services';
|
|
24
|
+
|
|
25
|
+
@NgModule({
|
|
26
|
+
providers: [
|
|
27
|
+
...SERVICES,
|
|
28
|
+
{
|
|
29
|
+
provide: Masonry,
|
|
30
|
+
useFactory: () => {
|
|
31
|
+
if (typeof window !== 'undefined' && (window as any)['Masonry']) {
|
|
32
|
+
return (window as any)['Masonry'];
|
|
33
|
+
}
|
|
34
|
+
// Return a mock for SSR
|
|
35
|
+
return class {
|
|
36
|
+
constructor() {
|
|
37
|
+
// no-op
|
|
38
|
+
}
|
|
39
|
+
layout() {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
reloadItems() {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
destroy() {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
imports: [
|
|
53
|
+
FormsModule,
|
|
54
|
+
ArticlesSharedModule.forFeature({
|
|
55
|
+
routing: false,
|
|
56
|
+
config: {
|
|
57
|
+
reducerFactory: getReducer,
|
|
58
|
+
type: Article,
|
|
59
|
+
apiUrl: environment.apiUrl,
|
|
60
|
+
entity: 'partners',
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
RouterModule.forChild(routes),
|
|
64
|
+
],
|
|
65
|
+
})
|
|
66
|
+
export class MuseumPartnersModule {}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
> Contrast with `mobilems-objects` (`ObjectsSharedModule.forFeature` over `MsObject`, no
|
|
70
|
+
> `reducerFactory`): here the module reuses `ArticlesSharedModule`, supplies `type: Article` with
|
|
71
|
+
> `reducerFactory: getReducer`, and there is deliberately **no `baseQuery`** in the config.
|
|
72
|
+
|
|
73
|
+
## `partners.routes.ts`
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { Route } from '@angular/router';
|
|
77
|
+
|
|
78
|
+
import { ItemComponent, ListComponent } from './pages';
|
|
79
|
+
|
|
80
|
+
export const routes: Route[] = [
|
|
81
|
+
{
|
|
82
|
+
path: ':id',
|
|
83
|
+
component: ItemComponent,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
path: ':id/:slug',
|
|
87
|
+
component: ItemComponent,
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
path: '',
|
|
91
|
+
component: ListComponent,
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Register in `apps/web/src/app/app.routes.ts`
|
|
97
|
+
|
|
98
|
+
Add the partners route to the `appRoutes` array (idempotently — if a `partnerzy` route already
|
|
99
|
+
exists, skip). Add it as a top-level route, and as a child of the `wyszukaj/:text` search route so
|
|
100
|
+
`/wyszukaj/:text/partnerzy` works and partners shows up among the search results.
|
|
101
|
+
|
|
102
|
+
Top-level — add to `appRoutes`:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
{
|
|
106
|
+
path: 'partnerzy',
|
|
107
|
+
loadChildren: () =>
|
|
108
|
+
import('@<PREFIX>/museum-partners/shell/angular').then(
|
|
109
|
+
(m) => m.MuseumPartnersModule,
|
|
110
|
+
),
|
|
111
|
+
},
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Search child — add to the `children` of the `wyszukaj/:text` route, before the
|
|
115
|
+
`{ path: '', redirectTo: 'obiekty' }` default:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
{
|
|
119
|
+
path: 'partnerzy',
|
|
120
|
+
loadChildren: () =>
|
|
121
|
+
import('@<PREFIX>/museum-partners/shell/angular').then(
|
|
122
|
+
(m) => m.MuseumPartnersModule,
|
|
123
|
+
),
|
|
124
|
+
},
|
|
125
|
+
```
|
|
@@ -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. Portable to macOS bash 3.2.
|
|
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,59 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# verify-module.sh <workspace-root> <PREFIX>
|
|
4
|
+
#
|
|
5
|
+
# Post-condition check for mobilems-partners: library created, ArticlesSharedModule wired over the
|
|
6
|
+
# Article type with its own reducer, the partner cards present in the partners lib, the partnerzy
|
|
7
|
+
# route registered (top-level + search child), and the Articles + objects-domain deps installed.
|
|
8
|
+
# macOS bash 3.2 safe.
|
|
9
|
+
set -eu
|
|
10
|
+
|
|
11
|
+
ROOT="${1:?usage: verify-module.sh <workspace-root> <PREFIX>}"
|
|
12
|
+
PREFIX="${2:?usage: verify-module.sh <workspace-root> <PREFIX>}"
|
|
13
|
+
cd "$ROOT" 2>/dev/null || { echo "ERROR: no such dir: $ROOT" >&2; exit 2; }
|
|
14
|
+
|
|
15
|
+
fail=0
|
|
16
|
+
pass() { echo " PASS: $1"; }
|
|
17
|
+
bad() { echo " FAIL: $1" >&2; fail=1; }
|
|
18
|
+
|
|
19
|
+
MOD=libs/museum-partners/shell/angular/src/lib/partners.module.ts
|
|
20
|
+
|
|
21
|
+
echo "== Library =="
|
|
22
|
+
[ -f "$MOD" ] && pass "MuseumPartnersModule present" || bad "partners.module.ts missing"
|
|
23
|
+
[ -f libs/museum-partners/domain/src/lib/entities/museum-partner.entity.ts ] && pass "MuseumPartner entity present" || bad "domain entity missing"
|
|
24
|
+
grep -q "class MuseumPartner" libs/museum-partners/domain/src/lib/entities/museum-partner.entity.ts 2>/dev/null && pass "MuseumPartner class declared" || bad "MuseumPartner class not declared"
|
|
25
|
+
grep -q "museum-partners/shell/angular" tsconfig.base.json && pass "tsconfig shell path added" || bad "tsconfig shell path missing"
|
|
26
|
+
grep -q "museum-partners/domain" tsconfig.base.json && pass "tsconfig domain path added" || bad "tsconfig domain path missing"
|
|
27
|
+
|
|
28
|
+
echo "== Module wiring =="
|
|
29
|
+
grep -q "ArticlesSharedModule.forFeature" "$MOD" 2>/dev/null && pass "ArticlesSharedModule.forFeature wired" || bad "ArticlesSharedModule.forFeature missing"
|
|
30
|
+
grep -q "entity: 'partners'" "$MOD" 2>/dev/null && pass "entity 'partners' configured" || bad "entity 'partners' missing"
|
|
31
|
+
grep -q "reducerFactory: getReducer" "$MOD" 2>/dev/null && pass "reducerFactory: getReducer configured" || bad "reducerFactory: getReducer missing"
|
|
32
|
+
|
|
33
|
+
echo "== +state =="
|
|
34
|
+
STATE=libs/museum-partners/shell/angular/src/lib/+state
|
|
35
|
+
[ -f "$STATE/partners.reducer.ts" ] && pass "reducer present" || bad "partners.reducer.ts missing"
|
|
36
|
+
grep -q "export function getReducer" "$STATE/partners.reducer.ts" 2>/dev/null && pass "getReducer exported" || bad "getReducer not exported in reducer"
|
|
37
|
+
|
|
38
|
+
echo "== UI components =="
|
|
39
|
+
COMP=libs/museum-partners/shell/angular/src/lib/components
|
|
40
|
+
[ -f "$COMP/grid-item/grid-item.component.ts" ] && pass "grid-item card present" || bad "components/grid-item missing"
|
|
41
|
+
[ -f "$COMP/list-item/list-item.component.ts" ] && pass "list-item card present" || bad "components/list-item missing"
|
|
42
|
+
|
|
43
|
+
echo "== Route registration =="
|
|
44
|
+
ROUTES=apps/web/src/app/app.routes.ts
|
|
45
|
+
grep -q "museum-partners/shell/angular" "$ROUTES" && pass "partners route registered" || bad "partners route not in app.routes.ts"
|
|
46
|
+
# top-level + search child — expect at least 2 occurrences
|
|
47
|
+
n=$(grep -c "museum-partners/shell/angular" "$ROUTES" || true)
|
|
48
|
+
[ "${n:-0}" -ge 2 ] && pass "registered top-level + search child ($n)" || bad "expected >=2 route registrations (top-level + search child), found $n"
|
|
49
|
+
grep -q "partnerzy" "$ROUTES" && pass "partnerzy path present" || bad "partnerzy path missing"
|
|
50
|
+
|
|
51
|
+
echo "== Deps =="
|
|
52
|
+
grep -q "@smartsoft001-mobilems/articles-domain" package.json && pass "articles-domain dep" || bad "articles-domain dep missing"
|
|
53
|
+
grep -q "@smartsoft001-mobilems/articles-shell-angular" package.json && pass "articles-shell-angular dep" || bad "articles-shell-angular dep missing"
|
|
54
|
+
grep -q "@smartsoft001-mobilems/articles-shell-dtos" package.json && pass "articles-shell-dtos dep" || bad "articles-shell-dtos dep missing"
|
|
55
|
+
grep -q "@smartsoft001-mobilems/objects-domain" package.json && pass "objects-domain dep" || bad "objects-domain dep missing"
|
|
56
|
+
|
|
57
|
+
echo
|
|
58
|
+
if [ "$fail" = 0 ]; then echo "VERIFY: all checks passed."; else echo "VERIFY: FAILED — fix the items above and re-run." >&2; fi
|
|
59
|
+
exit "$fail"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mobilems-project-init
|
|
3
|
+
description: Turn a generic scaffold-nx-workspace base into a MobilEMS museum web-app foundation — the MobilEMS DELTA (deps, Tailwind, runtime env, app.config providers, shared lib, static pages, app shell, .claude). Use whenever the user wants to initialize / bootstrap / set up a NEW MobilEMS or MuzaCMS museum app, "skonfiguruj projekt muzealny / mobilems", port a museum frontend, or asks to add the MobilEMS foundation on top of an existing Nx + Angular SSR scaffold. Produces the foundation ONLY — NO feature modules (objects, collections, articles, thematic publications); those are added by the mobilems-<module> skills afterwards.
|
|
4
|
+
user-invocable: true
|
|
5
|
+
allowed-tools: Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# MobilEMS project init
|
|
9
|
+
|
|
10
|
+
Apply the **MobilEMS delta** on top of a base produced by `scaffold-nx-workspace` (the generic
|
|
11
|
+
smartsoft Nx + Angular-SSR shell). The base gives you a buildable empty workspace: prefix already
|
|
12
|
+
threaded, scss-only, minimal `app.config.ts`, empty `app.routes.ts`, a generic `server.ts`, and a
|
|
13
|
+
shared lib that exports only `environment` + `EnvironmentService`. This skill upgrades that shell
|
|
14
|
+
into a MobilEMS museum **foundation** — everything the museum app needs _except_ the feature
|
|
15
|
+
modules.
|
|
16
|
+
|
|
17
|
+
**Why a delta (not a from-scratch generator):** the museum shared lib is ~15k lines of bespoke
|
|
18
|
+
Angular (header, footer, page renderer, filters, gallery, map, widgets, WCAG, SEO, …) that is
|
|
19
|
+
**not** published to npm. It cannot be regenerated from prose, so reference mode copies it from an
|
|
20
|
+
existing MobilEMS repo and threads the workspace prefix. Foundation-only mode is a degraded
|
|
21
|
+
fallback when no reference is available.
|
|
22
|
+
|
|
23
|
+
## Scope — the foundation only
|
|
24
|
+
|
|
25
|
+
This skill builds the museum **foundation**: the workspace it produces builds and runs on its own,
|
|
26
|
+
with **no `libs/museum-*` libraries, no feature shared components, and no feature routes** yet. The
|
|
27
|
+
feature modules are built by `mobilems-objects`, `mobilems-object-collections`, `mobilems-articles`,
|
|
28
|
+
and `mobilems-thematic-publications`, each of which adds its own library, shared components, npm
|
|
29
|
+
package, and routes. Keeping feature code out of the foundation is the layering rule that lets the
|
|
30
|
+
foundation build standalone (its shared library imports no feature package).
|
|
31
|
+
|
|
32
|
+
## Steps
|
|
33
|
+
|
|
34
|
+
### 0. Precondition — confirm a scaffold-nx-workspace base
|
|
35
|
+
|
|
36
|
+
Run `scripts/detect-base.sh <workspace-root>`. It checks for the base shell (`apps/web/src/server.ts`,
|
|
37
|
+
an empty-ish `app.routes.ts`, a shared lib barrel exporting only environment/EnvironmentService) and
|
|
38
|
+
that the MobilEMS delta is **not** already applied. If the base is missing, stop and tell the user to
|
|
39
|
+
run `/smart:scaffold-nx-workspace` first — do not try to create the Nx workspace here.
|
|
40
|
+
|
|
41
|
+
### 1. Detect the prefix (never re-propose)
|
|
42
|
+
|
|
43
|
+
The base already derived/confirmed/threaded the import-alias prefix. Read it from
|
|
44
|
+
`tsconfig.base.json` `paths` — the key `@<PREFIX>/angular`. Hold `<PREFIX>`; thread it into every
|
|
45
|
+
copied file (the reference repo uses `@msr`, so replacing `@msr` → `@<PREFIX>` is the main rewrite).
|
|
46
|
+
|
|
47
|
+
### 2. Choose mode
|
|
48
|
+
|
|
49
|
+
Default = **reference mode**. Ask the user (`AskUserQuestion`) for the path/URL of an existing
|
|
50
|
+
MobilEMS repo to copy the shared lib + static pages from (a local clone of one of the team's museum
|
|
51
|
+
apps). If they decline, or if invoked with a `foundation-only` argument, use **foundation-only** mode
|
|
52
|
+
(see "Modes" below).
|
|
53
|
+
|
|
54
|
+
### 3. npm dependencies
|
|
55
|
+
|
|
56
|
+
Add the MobilEMS framework + state + i18n + shared-UI deps per `references/npm-deps.md`. Versions
|
|
57
|
+
are resolved at run time to match the installed `@smartsoft001/angular` line — **never hardcode**.
|
|
58
|
+
Do NOT add the per-feature packages (`*-objects-*`, `*-articles-*`, `*-public-collections-*`) or
|
|
59
|
+
`online-3d-viewer` — those belong to the module skills.
|
|
60
|
+
|
|
61
|
+
### 4. Tailwind on top of scss
|
|
62
|
+
|
|
63
|
+
Layer Tailwind (class prefix `smart-`) onto the base's scss per `references/tailwind-styles.md`:
|
|
64
|
+
add `tailwind.config.js` + postcss wiring, and overwrite `apps/web/src/styles.scss` with the museum
|
|
65
|
+
global stylesheet (font-fallbacks, `.smart-container`, WCAG, masonry, fullscreen-dialog rules). The
|
|
66
|
+
stylesheet is pure CSS — copying it verbatim is safe even before the components it targets exist.
|
|
67
|
+
|
|
68
|
+
### 5. Runtime env — multimediaUrl + translations
|
|
69
|
+
|
|
70
|
+
Extend the base runtime-env infra per `references/server-env.md`: add `multimediaUrl` to
|
|
71
|
+
`environment.ts`/`.prod.ts`, the `/env.js` template, and the SSR allowed-hosts list; and add the
|
|
72
|
+
`/api/translations` endpoint to `server.ts`.
|
|
73
|
+
|
|
74
|
+
### 6. app.config.ts → MobilEMS providers
|
|
75
|
+
|
|
76
|
+
Replace the base's minimal providers with the full MobilEMS provider set per
|
|
77
|
+
`references/config-providers.md` (ngrx root + devtools, ngx-translate + `provideAppInitializer`
|
|
78
|
+
translation bootstrap, `MasonryModule`, `SharedModule.forRoot`, the three HTTP interceptors, the
|
|
79
|
+
`StyleService`/`AppService`→`NoOpAppService`/`ErrorService` overrides, `SEARCH_CONFIG_TOKEN`, and
|
|
80
|
+
`withI18nSupport()` on hydration).
|
|
81
|
+
|
|
82
|
+
### 7. Shared lib — populate the placeholders (reference mode)
|
|
83
|
+
|
|
84
|
+
Follow `references/shared-lib.md`. Build the **foundation shared components** — every shared
|
|
85
|
+
component that depends only on Angular + the framework packages + other foundation shared components.
|
|
86
|
+
Run `python3 scripts/classify-shared-components.py` against the reference's
|
|
87
|
+
`libs/shared/angular/src/lib/components` to list which shared components are FOUNDATION (build here)
|
|
88
|
+
vs FEATURE-OWNED (built by a module skill, because they import a feature package). Build the
|
|
89
|
+
foundation components (including the home-page carousels) + all services/pipes/directives/tools/models
|
|
90
|
+
|
|
91
|
+
- `configs.module.ts`, thread `<PREFIX>`, export them from the barrels, and build the `widget`
|
|
92
|
+
container + `models/objects.model.ts` with their foundation parts. A shared component that imports a
|
|
93
|
+
feature domain package is feature code — a module skill builds it.
|
|
94
|
+
|
|
95
|
+
### 8. App shell + static pages + routes
|
|
96
|
+
|
|
97
|
+
Follow `references/app-shell.md`: copy the `App` root component (`app.ts`/`app.html`/`app.scss`) and
|
|
98
|
+
the static pages (`home`, `page`, `contact`, `search`, `not-found`) + their resolvers, thread
|
|
99
|
+
`<PREFIX>`, and build `app.routes.ts` with the app's static routes (home, pages, contact, search,
|
|
100
|
+
catch-all). Each module skill adds its own feature route to the `appRoutes` array when it runs
|
|
101
|
+
(`article-preview` is articles-coupled — `mobilems-articles` adds it, not the foundation).
|
|
102
|
+
|
|
103
|
+
### 9. .claude extension
|
|
104
|
+
|
|
105
|
+
Apply `references/claude-config.md`: add `flow@mobilems` to `enabledPlugins`, grow the
|
|
106
|
+
MobilEMS-specific permissions / MCP allow-lists, and seed `tools/specs` + `tools/prompts` pointers.
|
|
107
|
+
|
|
108
|
+
### 10. Verify
|
|
109
|
+
|
|
110
|
+
Run `scripts/verify-init.sh <workspace-root> <PREFIX>`. It asserts the delta landed (Tailwind,
|
|
111
|
+
multimediaUrl, MobilEMS providers, populated shared-lib barrel) AND the foundation is self-contained
|
|
112
|
+
(no `libs/museum-*`, no feature routes, and the build-safety invariant — no file under
|
|
113
|
+
`libs/shared/angular/src` imports a feature package). Fix and re-run until it passes. Gate
|
|
114
|
+
`npm install` behind an explicit ask — skip it during self-validation/eval.
|
|
115
|
+
|
|
116
|
+
## Modes
|
|
117
|
+
|
|
118
|
+
- **Reference mode (default):** copies the shared lib + pages from a real MobilEMS repo and threads
|
|
119
|
+
the prefix. This is the only mode that regenerates the full foundation, because the shared lib is
|
|
120
|
+
not in npm.
|
|
121
|
+
- **Foundation-only (fallback):** do steps 1, 3, 4, 5, 9 (deps, Tailwind, env, .claude) and scaffold a
|
|
122
|
+
reduced `app.config.ts` that does NOT import local shared-lib code (omit the interceptors + the
|
|
123
|
+
`App` shell that need it). Leave a `MOBILEMS-FOUNDATION-TODO.md` listing what reference mode would
|
|
124
|
+
have copied (shared lib, pages, full app.config, app shell) so the user can supply a reference
|
|
125
|
+
later. Be honest that this mode does not produce a runnable museum UI on its own.
|
|
126
|
+
|
|
127
|
+
## Notes
|
|
128
|
+
|
|
129
|
+
- This skill assumes the base Nx + Angular-SSR workspace already exists — it patches MobilEMS onto
|
|
130
|
+
it and never runs `create-nx-workspace`.
|
|
131
|
+
- Bundled `references/` + `scripts/` ship automatically (the whole `src/plugins/**` tree is copied to
|
|
132
|
+
dist). Do NOT hand-edit `plugin.json` — the version is auto-synced at build.
|
|
133
|
+
- The feature work — feature libs, their npm packages, routes, and feature shared components — is
|
|
134
|
+
built by the `mobilems-<module>` skills, not here.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# App shell + static pages + routes
|
|
2
|
+
|
|
3
|
+
Build the root `App` component, the static pages, and the app routing by copying from the reference's
|
|
4
|
+
`apps/web/src/app` and threading `<PREFIX>`. The foundation owns the shell, the static pages, and the
|
|
5
|
+
routing table's static routes; each feature module skill adds its own routes.
|
|
6
|
+
|
|
7
|
+
## App root — `app.ts` / `app.html` / `app.scss`
|
|
8
|
+
|
|
9
|
+
Copy verbatim and thread `<PREFIX>`. The root component imports the `COMPONENTS` array +
|
|
10
|
+
`SkipLinksComponent` from `@<PREFIX>/angular`, injects `ConfigsFacade` + `SeoService` (from
|
|
11
|
+
`@smartsoft001-mobilems/angular`), `LocalStorageService` (shared lib) and `Router`; it inits the
|
|
12
|
+
language, loads the global `Config` in `ngOnInit`, and focuses `#skip-links` on each `NavigationEnd`.
|
|
13
|
+
`app.html`:
|
|
14
|
+
|
|
15
|
+
```html
|
|
16
|
+
<app-skip-links></app-skip-links>
|
|
17
|
+
<app-app [options]="options">
|
|
18
|
+
<header tabindex="-1"><app-header></app-header></header>
|
|
19
|
+
<footer><app-footer></app-footer></footer>
|
|
20
|
+
</app-app>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Static pages
|
|
24
|
+
|
|
25
|
+
Copy `pages/{home,page,contact,search,not-found}` + the `home` and `page` resolvers, and thread
|
|
26
|
+
`<PREFIX>`. These use only foundation shared components:
|
|
27
|
+
|
|
28
|
+
- `home.component` uses the foundation carousels (`NewObjectsCarouselComponent`,
|
|
29
|
+
`NewsCarouselComponent`, `PartnersCarouselComponent`) and the `IObject`/`IArticle`/`IPartner` types
|
|
30
|
+
from the shared `models/` dir, plus the `DataService` home loaders — all foundation code (see
|
|
31
|
+
`references/shared-lib.md`). The home page renders fully; its carousels populate from the API at
|
|
32
|
+
runtime.
|
|
33
|
+
- `search.component` renders results through a `<router-outlet>`; it has no feature import.
|
|
34
|
+
|
|
35
|
+
Run a feature-package grep over the pages you copy as a guard. **Do not copy `article-preview`** — the
|
|
36
|
+
reference's `article-preview` page imports `@smartsoft001-mobilems/articles-domain` (it previews an
|
|
37
|
+
Article), so it is feature code, not foundation. The `mobilems-articles` skill builds it (and its
|
|
38
|
+
route) when it adds an article module. If your reference has any other page that imports a feature
|
|
39
|
+
package, leave it for the owning module skill too.
|
|
40
|
+
|
|
41
|
+
## `app.routes.ts` — the app routing table
|
|
42
|
+
|
|
43
|
+
Build `appRoutes` with the app's static routes — home, dynamic pages, contact, search, and the
|
|
44
|
+
catch-all. Each feature module skill adds its own route (a lazy `loadChildren`) to this `appRoutes`
|
|
45
|
+
array and a matching child under the `wyszukaj/:text` search route when it runs (and `mobilems-articles`
|
|
46
|
+
adds the `article-preview` route).
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { Route } from '@angular/router';
|
|
50
|
+
|
|
51
|
+
import { homeResolver } from './pages/home/home.resolver';
|
|
52
|
+
import { pageResolver } from './pages/page/page.resolver';
|
|
53
|
+
|
|
54
|
+
export const appRoutes: Route[] = [
|
|
55
|
+
{ path: '', pathMatch: 'full', redirectTo: 'strona-glowna' },
|
|
56
|
+
{
|
|
57
|
+
path: 'strona/:id',
|
|
58
|
+
loadComponent: () =>
|
|
59
|
+
import('./pages/page/page.component').then((m) => m.PageComponent),
|
|
60
|
+
resolve: { pageData: pageResolver },
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
path: 'strona/:id/:slug',
|
|
64
|
+
loadComponent: () =>
|
|
65
|
+
import('./pages/page/page.component').then((m) => m.PageComponent),
|
|
66
|
+
resolve: { pageData: pageResolver },
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
path: 'strona-glowna',
|
|
70
|
+
loadComponent: () =>
|
|
71
|
+
import('./pages/home/home.component').then((m) => m.HomeComponent),
|
|
72
|
+
resolve: { pageData: homeResolver },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
path: 'kontakt',
|
|
76
|
+
loadComponent: () =>
|
|
77
|
+
import('./pages/contact/contact.component').then(
|
|
78
|
+
(m) => m.ContactComponent,
|
|
79
|
+
),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
path: 'wyszukaj',
|
|
83
|
+
children: [
|
|
84
|
+
{
|
|
85
|
+
path: ':text',
|
|
86
|
+
loadComponent: () =>
|
|
87
|
+
import('./pages/search/search.component').then(
|
|
88
|
+
(m) => m.SearchComponent,
|
|
89
|
+
),
|
|
90
|
+
children: [{ path: '', redirectTo: 'obiekty', pathMatch: 'full' }],
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
path: '**',
|
|
96
|
+
loadComponent: () =>
|
|
97
|
+
import('./pages/not-found/not-found.component').then(
|
|
98
|
+
(m) => m.NotFoundComponent,
|
|
99
|
+
),
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
> The search view defaults to the objects results (`redirectTo: 'obiekty'`); the route resolves once
|
|
105
|
+
> the objects module is present. A module skill adds its route by inserting a `loadChildren` entry
|
|
106
|
+
> into `appRoutes` (top level) and into the `wyszukaj/:text` `children` array, immediately before the
|
|
107
|
+
> `{ path: '', redirectTo: 'obiekty' }` default — see each module skill's `module-and-routes.md`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# .claude extension — flow@mobilems + MobilEMS perms
|
|
2
|
+
|
|
3
|
+
The base seeded a generic `.claude/settings.json` (smart@smartsoft + nx plugins, safety/audit hooks,
|
|
4
|
+
a generic allow-list). MobilEMS adds the `flow@mobilems` plugin and the museum-specific
|
|
5
|
+
permission / MCP allow-lists. **Extend, do not replace** the base file — keep its hooks and `env`.
|
|
6
|
+
|
|
7
|
+
## `.claude/settings.json`
|
|
8
|
+
|
|
9
|
+
1. **`enabledPlugins`** — add `flow@mobilems` (keep the existing `smart@smartsoft` + `nx@nx-claude-plugins`):
|
|
10
|
+
```json
|
|
11
|
+
"enabledPlugins": {
|
|
12
|
+
"flow@mobilems": true,
|
|
13
|
+
"smart@smartsoft": true,
|
|
14
|
+
"nx@nx-claude-plugins": true
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
2. **`permissions.allow`** — add the MobilEMS working set on top of the base git/nx/fs allows:
|
|
18
|
+
- Playwright MCP (`mcp__playwright__browser_*`) + accessibility-scanner MCP
|
|
19
|
+
(`mcp__accessibility-scanner__*`) — used by the UI / a11y skills.
|
|
20
|
+
- `WebSearch`, and `WebFetch(domain:…)` for `www.npmjs.com`, `github.com`,
|
|
21
|
+
`docs.anthropic.com`, `linear.app`, plus the project's own museum portal domain (ask the user
|
|
22
|
+
for it, or leave a placeholder comment) and `localhost`.
|
|
23
|
+
- `Bash(npm start)`, `Bash(nx:*)`, `Bash(lsof:*)`, `Bash(mkdir:*)` for serve/screenshot flows.
|
|
24
|
+
- Keep `permissions.ask` (`git commit`/`git push`/`gh pr create`) from the base.
|
|
25
|
+
3. **`extraKnownMarketplaces`** — keep the base's `nx-claude-plugins`. The `mobilems` and `smart`
|
|
26
|
+
marketplaces are resolved from the installed `@smartsoft001*/claude-plugins` packages.
|
|
27
|
+
|
|
28
|
+
> Don't copy the reference's full domain allow-list verbatim — it carries one museum's specific
|
|
29
|
+
> hosts (its own portal domain, project n8n/maia webhooks). Seed the generic-useful entries and let
|
|
30
|
+
> the project grow its own.
|
|
31
|
+
|
|
32
|
+
## tools/specs + tools/prompts
|
|
33
|
+
|
|
34
|
+
Seed pointers so the museum conventions are discoverable (the framework repo keeps the canonical
|
|
35
|
+
copies under `tools/specs/{layers,styles,tests}.md` + `tools/prompts/*`). Either copy those files
|
|
36
|
+
from the reference repo, or drop a short `tools/README.md` linking to them. These are documentation
|
|
37
|
+
aids — not required for the build, so keep this light.
|
|
38
|
+
|
|
39
|
+
## CLAUDE.md / AGENTS.md
|
|
40
|
+
|
|
41
|
+
The base wrote a trimmed generic `CLAUDE.md` + the Nx `AGENTS.md`. Optionally append a short
|
|
42
|
+
"MobilEMS" section to `CLAUDE.md` noting: feature modules are added by the `mobilems-<module>`
|
|
43
|
+
skills, styling is Tailwind (`smart-` prefix) on scss, and runtime env adds `multimediaUrl`. Keep it
|
|
44
|
+
brief — the authoritative guidance lives in the plugin skills.
|