@jahia/agentic 0.3.0 → 0.4.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 (153) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/claude/.claude/agents/cnd-child-nodes.md +74 -0
  3. package/dist/claude/.claude/agents/cnd-jahia-mixins.md +113 -0
  4. package/dist/claude/.claude/agents/cnd-numbers-dates.md +61 -0
  5. package/dist/claude/.claude/agents/cnd-string-selectors.md +94 -0
  6. package/dist/claude/.claude/agents/jahia-cnd-author.md +130 -0
  7. package/dist/claude/.claude/agents/jahia-dev-worker.md +264 -0
  8. package/dist/claude/.claude/agents/jahia-reviewer.md +105 -0
  9. package/dist/claude/.claude/rules/jahia.md +15 -6
  10. package/dist/claude/.claude/skills/jahia/SKILL.md +5 -1
  11. package/dist/claude/.claude/skills/jahia-dev-accessibility/SKILL.md +3 -3
  12. package/dist/claude/.claude/skills/jahia-dev-build-component/SKILL.md +10 -7
  13. package/dist/claude/.claude/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  14. package/dist/claude/.claude/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  15. package/dist/claude/.claude/skills/jahia-dev-create-view/SKILL.md +3 -3
  16. package/dist/claude/.claude/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  17. package/dist/claude/.claude/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  18. package/dist/claude/.claude/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  19. package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  20. package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  21. package/dist/claude/.claude/skills/jahia-dev-site-review/SKILL.md +70 -0
  22. package/dist/claude/.claude/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  23. package/dist/claude/.claude/skills/jahia-dev-start-local/SKILL.md +18 -26
  24. package/dist/claude/.claude/skills/jahia-orchestrate/SKILL.md +148 -0
  25. package/dist/claude/.claude/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  26. package/dist/claude/CLAUDE.md +16 -7
  27. package/dist/codex/.agents/skills/jahia/SKILL.md +5 -1
  28. package/dist/codex/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  29. package/dist/codex/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  30. package/dist/codex/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  31. package/dist/codex/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  32. package/dist/codex/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  33. package/dist/codex/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  34. package/dist/codex/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  35. package/dist/codex/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  36. package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  37. package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  38. package/dist/codex/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  39. package/dist/codex/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  40. package/dist/codex/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  41. package/dist/codex/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  42. package/dist/codex/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  43. package/dist/codex/.codex/agents/cnd-child-nodes.toml +3 -0
  44. package/dist/codex/.codex/agents/cnd-jahia-mixins.toml +3 -0
  45. package/dist/codex/.codex/agents/cnd-numbers-dates.toml +3 -0
  46. package/dist/codex/.codex/agents/cnd-string-selectors.toml +3 -0
  47. package/dist/codex/.codex/agents/jahia-cnd-author.toml +3 -0
  48. package/dist/codex/.codex/agents/jahia-dev-worker.toml +3 -0
  49. package/dist/codex/.codex/agents/jahia-reviewer.toml +3 -0
  50. package/dist/codex/AGENTS.md +17 -8
  51. package/dist/copilot/.agents/skills/jahia/SKILL.md +5 -1
  52. package/dist/copilot/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  53. package/dist/copilot/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  54. package/dist/copilot/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  55. package/dist/copilot/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  56. package/dist/copilot/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  57. package/dist/copilot/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  58. package/dist/copilot/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  59. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  60. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  61. package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  62. package/dist/copilot/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  63. package/dist/copilot/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  64. package/dist/copilot/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  65. package/dist/copilot/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  66. package/dist/copilot/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  67. package/dist/copilot/AGENTS.md +17 -8
  68. package/dist/cursor/.agents/skills/jahia/SKILL.md +5 -1
  69. package/dist/cursor/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  70. package/dist/cursor/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  71. package/dist/cursor/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  72. package/dist/cursor/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  73. package/dist/cursor/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  74. package/dist/cursor/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  75. package/dist/cursor/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  76. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  77. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  78. package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  79. package/dist/cursor/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  80. package/dist/cursor/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  81. package/dist/cursor/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  82. package/dist/cursor/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  83. package/dist/cursor/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  84. package/dist/cursor/.cursor/agents/cnd-child-nodes.md +74 -0
  85. package/dist/cursor/.cursor/agents/cnd-jahia-mixins.md +113 -0
  86. package/dist/cursor/.cursor/agents/cnd-numbers-dates.md +61 -0
  87. package/dist/cursor/.cursor/agents/cnd-string-selectors.md +94 -0
  88. package/dist/cursor/.cursor/agents/jahia-cnd-author.md +130 -0
  89. package/dist/cursor/.cursor/agents/jahia-dev-worker.md +264 -0
  90. package/dist/cursor/.cursor/agents/jahia-reviewer.md +105 -0
  91. package/dist/cursor/.cursor/rules/jahia.mdc +15 -6
  92. package/dist/gemini/.agents/skills/jahia/SKILL.md +5 -1
  93. package/dist/gemini/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  94. package/dist/gemini/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  95. package/dist/gemini/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  96. package/dist/gemini/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  97. package/dist/gemini/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  98. package/dist/gemini/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  99. package/dist/gemini/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  100. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  101. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  102. package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  103. package/dist/gemini/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  104. package/dist/gemini/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  105. package/dist/gemini/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  106. package/dist/gemini/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  107. package/dist/gemini/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  108. package/dist/gemini/AGENTS.md +17 -8
  109. package/dist/gemini/GEMINI.md +2 -2
  110. package/dist/index.js +13 -0
  111. package/dist/opencode/.agents/skills/jahia/SKILL.md +5 -1
  112. package/dist/opencode/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
  113. package/dist/opencode/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
  114. package/dist/opencode/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  115. package/dist/opencode/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  116. package/dist/opencode/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
  117. package/dist/opencode/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  118. package/dist/opencode/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  119. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  120. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  121. package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  122. package/dist/opencode/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
  123. package/dist/opencode/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  124. package/dist/opencode/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
  125. package/dist/opencode/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
  126. package/dist/opencode/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  127. package/dist/opencode/.opencode/agents/cnd-child-nodes.md +74 -0
  128. package/dist/opencode/.opencode/agents/cnd-jahia-mixins.md +113 -0
  129. package/dist/opencode/.opencode/agents/cnd-numbers-dates.md +61 -0
  130. package/dist/opencode/.opencode/agents/cnd-string-selectors.md +94 -0
  131. package/dist/opencode/.opencode/agents/jahia-cnd-author.md +130 -0
  132. package/dist/opencode/.opencode/agents/jahia-dev-worker.md +264 -0
  133. package/dist/opencode/.opencode/agents/jahia-reviewer.md +105 -0
  134. package/dist/opencode/AGENTS.md +17 -8
  135. package/dist/windsurf/.windsurf/rules/jahia.md +15 -6
  136. package/dist/windsurf/.windsurf/skills/jahia/SKILL.md +5 -1
  137. package/dist/windsurf/.windsurf/skills/jahia-dev-accessibility/SKILL.md +3 -3
  138. package/dist/windsurf/.windsurf/skills/jahia-dev-build-component/SKILL.md +10 -7
  139. package/dist/windsurf/.windsurf/skills/jahia-dev-create-page-template/SKILL.md +59 -21
  140. package/dist/windsurf/.windsurf/skills/jahia-dev-create-template-set/SKILL.md +20 -47
  141. package/dist/windsurf/.windsurf/skills/jahia-dev-create-view/SKILL.md +3 -3
  142. package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/SKILL.md +43 -486
  143. package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
  144. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/SKILL.md +79 -0
  145. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
  146. package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
  147. package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/SKILL.md +70 -0
  148. package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
  149. package/dist/windsurf/.windsurf/skills/jahia-dev-start-local/SKILL.md +18 -26
  150. package/dist/windsurf/.windsurf/skills/jahia-orchestrate/SKILL.md +148 -0
  151. package/dist/windsurf/.windsurf/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
  152. package/dist/windsurf/AGENTS.md +17 -8
  153. package/package.json +1 -1
@@ -14,35 +14,72 @@ A **page template** defines the full layout of a page. It is registered with `co
14
14
 
15
15
  ## Step 1 — Create the template file
16
16
 
17
- Page templates live in `src/templates/Page/`. Name the file `<templateName>.server.tsx`.
17
+ Page templates live in `src/templates/<ModuleName>Template/`. Name the file `default.server.tsx`.
18
18
 
19
19
  ```tsx
20
- import { Area, AbsoluteArea, jahiaComponent } from "@jahia/javascript-modules-library";
21
- import { Layout } from "../Layout.jsx";
20
+ import React from "react";
21
+ import { Area, AbsoluteArea, getChildNodes, buildNodeUrl, jahiaComponent } from "@jahia/javascript-modules-library";
22
+ import styles from "./template.module.css";
22
23
 
23
24
  jahiaComponent(
24
25
  {
25
26
  componentType: "template", // "template" for full pages, not "view"
26
27
  nodeType: "jnt:page", // always jnt:page for page templates
27
- displayName: "Single Column",
28
- name: "singleColumn", // used in Jahia UI when selecting a template
28
+ displayName: "Default Template",
29
+ name: "default",
30
+ },
31
+ ({ "jcr:title": title }, { renderContext, mainNode }) => {
32
+ // Pages live under /sites/<key>/home — not directly under the site node
33
+ const siteHome = renderContext.getSite().getNode("home");
34
+ const navPages = getChildNodes(siteHome, -1, 0, n => n.isNodeType("jnt:page"));
35
+ const siteName = renderContext.getSite().getPropertyAsString("j:siteTitle") ?? renderContext.getSite().getName();
36
+ return (
37
+ <html lang="en">
38
+ <head>
39
+ <meta charSet="UTF-8" />
40
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
41
+ {/* jcr:title is the short page name — template appends site name for SEO */}
42
+ <title>{title}{siteName ? ` | ${siteName}` : ""}</title>
43
+ </head>
44
+ <body>
45
+ <a href="#main-content" className={styles.skipLink}>Skip to main content</a>
46
+ <header className={styles.header}>
47
+ <nav aria-label="Main navigation">
48
+ <ul className={styles.navList}>
49
+ <li key={siteHome.getPath()}>
50
+ <a href={buildNodeUrl(siteHome)} aria-current={siteHome.getPath() === mainNode.getPath() ? "page" : undefined}>
51
+ {siteHome.getPropertyAsString("jcr:title") ?? siteHome.getName()}
52
+ </a>
53
+ </li>
54
+ {navPages.map(page => (
55
+ <li key={page.getPath()}>
56
+ <a
57
+ href={buildNodeUrl(page)}
58
+ aria-current={page.getPath() === mainNode.getPath() ? "page" : undefined}
59
+ >
60
+ {page.getPropertyAsString("jcr:title") ?? page.getName()}
61
+ </a>
62
+ </li>
63
+ ))}
64
+ </ul>
65
+ </nav>
66
+ </header>
67
+ <main id="main-content">
68
+ <h1 className={styles.pageTitle}>{title}</h1>
69
+ <Area name="pagecontent" />
70
+ </main>
71
+ <footer className={styles.footer}>
72
+ <AbsoluteArea name="footer" parent={renderContext.getSite()} />
73
+ <p className={styles.copyright}>{"© "}{renderContext.getSite().getName()}</p>
74
+ </footer>
75
+ </body>
76
+ </html>
77
+ );
29
78
  },
30
- ({ "jcr:title": title }, { renderContext }) => (
31
- <Layout title={title}>
32
- <Area name="header" nodeType="namespace:header" />
33
- <main style={{ maxWidth: "40rem", margin: "0 auto" }}>
34
- <Area name="main" />
35
- </main>
36
- <AbsoluteArea
37
- name="footer"
38
- parent={renderContext.getSite()}
39
- nodeType="namespace:footer"
40
- />
41
- </Layout>
42
- ),
43
79
  );
44
80
  ```
45
81
 
82
+
46
83
  ---
47
84
 
48
85
  ## Step 2 — Choose: Area vs AbsoluteArea
@@ -266,13 +303,14 @@ After deploying, the new template will appear in the **template selection** step
266
303
  ---
267
304
 
268
305
  ## Validation checklist
269
- - [ ] File is in `src/templates/Page/`
270
306
  - [ ] `componentType: "template"` and `nodeType: "jnt:page"`
271
307
  - [ ] `name` is set (used in Jahia UI template picker)
308
+ - [ ] Skip link present: `<a href="#main-content">Skip to main content</a>`
309
+ - [ ] Nav built from `getChildNodes(site.getNode('home'), ...)` — pages are children of `home`, not of the site node
310
+ - [ ] `<h1>{title}</h1>` in the template — no `<h1>` in any component
311
+ - [ ] `<footer>` landmark always has visible content (never empty)
272
312
  - [ ] Areas use a custom area node type (not bare `<Area name="..."/>`)
273
313
  - [ ] Custom area type has `jmix:list`, `jmix:hiddenType`, and `orderable`
274
- - [ ] `AbsoluteArea` uses `renderContext.getSite()` as parent
275
- - [ ] Structural container nodes use `jmix:hiddenType` (hidden from picker)
276
314
  - [ ] Decision made: page template vs sectioning component (see Step 4)
277
315
  - [ ] `yarn build && yarn jahia-deploy` run and template appears in Jahia UI
278
316
 
@@ -119,66 +119,39 @@ yarn build && yarn jahia-deploy
119
119
 
120
120
  Verify the module is installed:
121
121
 
122
- ```bash
123
- curl -s -u root:root1234 -H "Origin: http://localhost:8080" \
124
- -X POST http://localhost:8080/modules/graphql \
125
- -H "Content-Type: application/json" \
126
- -d '{"query":"{ jcr { nodeByPath(path:\"/modules/<module-name>\") { name } } }"}'
122
+ ```
123
+ tool: content.get
124
+ args: { "path": "/modules/<module-name>" }
127
125
  ```
128
126
 
129
- Replace `<module-name>` with the `name` from `package.json`. The response should contain `"name": "<module-name>"`.
127
+ Replace `<module-name>` with the `name` from `package.json`. The response should contain the module node.
130
128
 
131
129
  ---
132
130
 
133
131
  ## Step 5 — Create a new site in Jahia
134
132
 
135
- After the module is deployed, create the site via the Provisioning API — **do not use the UI**.
136
-
137
- > ⚠️ **CRITICAL: syntax is `- createSite: ""`** — the empty string `""` after the colon is **mandatory**. Without it, Jahia returns HTTP 200 but silently creates nothing. Using `- createSite:` with nested properties is **wrong and will fail silently**.
133
+ After the module is deployed, create the site via MCP:
138
134
 
139
- ```bash
140
- MODULE_NAME=<module-name> # value of "name" in package.json
141
-
142
- curl -u root:root1234 \
143
- -X POST \
144
- -H "Content-Type: application/yaml" \
145
- --data-binary "- createSite: \"\"
146
- siteKey: ${MODULE_NAME}
147
- title: \"My Site\"
148
- defaultLanguage: en
149
- serverName: localhost
150
- templateSet: ${MODULE_NAME}" \
151
- http://localhost:8080/modules/api/provisioning
152
135
  ```
153
-
154
- Or write the script to a file and POST it:
155
-
156
- ```bash
157
- MODULE_NAME=<module-name>
158
-
159
- cat > /tmp/create-site.yaml <<EOF
160
- - createSite: ""
161
- siteKey: ${MODULE_NAME}
162
- title: "My Site"
163
- defaultLanguage: en
164
- serverName: localhost
165
- templateSet: ${MODULE_NAME}
166
- EOF
167
-
168
- curl -u root:root1234 -X POST -H "Content-Type: application/yaml" \
169
- --data-binary @/tmp/create-site.yaml \
170
- http://localhost:8080/modules/api/provisioning
136
+ tool: site.create
137
+ args: {
138
+ "siteKey": "<module-name>",
139
+ "title": "My Site",
140
+ "templateSet": "<module-name>",
141
+ "defaultLanguage": "en",
142
+ "serverName": "localhost"
143
+ }
171
144
  ```
172
145
 
146
+ Replace `<module-name>` with the `name` from `package.json`. `templateSet` must exactly match the deployed module name.
147
+
173
148
  Verify the site was created:
174
- ```bash
175
- curl -s -u root:root1234 \
176
- -H "Content-Type: application/json" -H "Origin: http://localhost:8080" \
177
- -X POST http://localhost:8080/modules/graphql \
178
- -d "{\"query\":\"{ jcr { nodeByPath(path:\\\"/sites/${MODULE_NAME}\\\") { name } } }\"}"
149
+
150
+ ```
151
+ tool: site.list
179
152
  ```
180
153
 
181
- The response must contain `"name": "<module-name>"`. If the path returns `null`, the site was not created — check that `templateSet` exactly matches the deployed module name.
154
+ The site key must appear in the response. If it does not, check that `templateSet` exactly matches the deployed module name.
182
155
 
183
156
  ---
184
157
 
@@ -229,4 +202,4 @@ If anything goes wrong during setup or scaffolding, refer to the official Jahia
229
202
  - [ ] Module directory created with expected structure
230
203
  - [ ] `yarn install` completes without errors
231
204
  - [ ] `yarn build && yarn jahia-deploy` succeeds — module appears at `/modules/<name>` in JCR
232
- - [ ] Site created with `createSite: ""` — JCR confirms `/sites/<name>` exists
205
+ - [ ] Site created with `site.create` — `site.list` confirms site key exists
@@ -100,11 +100,11 @@ Every `<img>` must have an `alt` attribute. Decorative images use `alt=""`. Info
100
100
  // ❌ Missing alt
101
101
  <img src={buildNodeUrl(props.image)} />
102
102
 
103
- // ✅ Descriptive alt from content
104
- <img src={buildNodeUrl(props.image)} alt={props.imageAlt ?? ""} />
103
+ // ✅ Alt from the image node's title (no extra CND property needed)
104
+ <img src={buildNodeUrl(props.image)} alt={props.image?.getPropertyAsString("jcr:title") ?? ""} />
105
105
  ```
106
106
 
107
- Add `- imageAlt (string) i18n` to the CND and `imageAlt?: string` to `types.ts` for any type with an image field.
107
+ The image node already has `jcr:title` (from `mix:title`). **Do not add `imageAlt (string) i18n`** to the CND it forces editors to enter duplicate data.
108
108
 
109
109
  ### Colour contrast
110
110