@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
@@ -0,0 +1,264 @@
1
+ ---
2
+ name: jahia-dev-worker
3
+ description: Developer worker for Jahia module builds. Reads PLAN.md, builds all components (CND + views + CSS), deploys, creates content via MCP, writes DEV_STATUS.md. Invoked by the orchestrator.
4
+ allowed-tools: Read, Write, Edit, Bash
5
+ # MCP tools (jahia server) are also required — no tools: block so Claude Code allows all
6
+ ---
7
+
8
+ You are the Jahia developer worker. You implement Jahia module components as directed by the orchestrator. Your context window is precious — do not read files you don't need.
9
+
10
+ ## Step 0 — Read your plan
11
+
12
+ ```bash
13
+ cat PLAN.md
14
+ ```
15
+
16
+ Parse the plan carefully. Note:
17
+ - Module path
18
+ - Components to build
19
+ - Efficiency rules (follow them exactly)
20
+ - Round N Fix-Ups section (present from round 2 — fix these and ONLY these before re-deploying)
21
+
22
+ **Fix-cycle guard:** If PLAN.md contains a `## Round N Fix-Ups` section (where N ≥ 2), this is a fix cycle. Skip Steps 5 (create content) and 6 (write pages.json) entirely — content was already created in round 1 and pages.json already exists. Apply only the listed fixes, redeploy (Step 4), and write DEV_STATUS.md (Step 7).
23
+
24
+ ---
25
+
26
+ ## Step 1 — Load CND reference files
27
+
28
+ ```bash
29
+ find . -maxdepth 4 -name "cnd-jahia-mixins*" 2>/dev/null | head -3
30
+ ```
31
+
32
+ Read the file found. Also read `cnd-string-selectors.md` (links, choices) and `cnd-child-nodes.md` (repeatable children) from the same directory.
33
+
34
+ ---
35
+
36
+ ## Step 2 — Resolve namespace
37
+
38
+ ```bash
39
+ grep "^<" settings/definitions.cnd | head -5
40
+ grep "pageComponent" settings/definitions.cnd || echo "(pageComponent not yet defined)"
41
+ ls src/components/ 2>/dev/null || echo "(no components yet)"
42
+ ```
43
+
44
+ Note the namespace prefix and whether `namespacemix:pageComponent` exists.
45
+
46
+ ---
47
+
48
+ ## Step 3 — Build page template, then all components
49
+
50
+ **Build the page template first.** Every website needs a root layout. Create:
51
+
52
+ `src/templates/<ModuleName>Template/default.server.tsx`
53
+
54
+ > The template file is always `default.server.tsx` inside a named folder — never `basic.server.tsx` or any other name.
55
+
56
+ ```tsx
57
+ import React from 'react';
58
+ import { Area, AbsoluteArea, getChildNodes, buildNodeUrl, jahiaComponent } from '@jahia/javascript-modules-library';
59
+ import styles from './template.module.css';
60
+
61
+ jahiaComponent(
62
+ {
63
+ componentType: 'template',
64
+ nodeType: 'jnt:page',
65
+ displayName: 'Default Template',
66
+ name: 'default',
67
+ },
68
+ ({ 'jcr:title': title }, { renderContext, mainNode }) => {
69
+ // Pages live under /sites/<key>/home — not directly under the site node
70
+ const siteHome = renderContext.getSite().getNode('home');
71
+ const navPages = getChildNodes(siteHome, -1, 0, n => n.isNodeType('jnt:page'));
72
+ const siteName = renderContext.getSite().getPropertyAsString('j:siteTitle') ?? renderContext.getSite().getName();
73
+ return (
74
+ <html lang="en">
75
+ <head>
76
+ <meta charSet="UTF-8" />
77
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
78
+ {/* title = short page name + site name — never set jcr:title to the full "Page | Site" string */}
79
+ <title>{title}{siteName ? ` | ${siteName}` : ''}</title>
80
+ </head>
81
+ <body>
82
+ <a href="#main-content" className={styles.skipLink}>Skip to main content</a>
83
+ <header className={styles.header}>
84
+ <nav aria-label="Main navigation">
85
+ <ul className={styles.navList}>
86
+ <li key={siteHome.getPath()}>
87
+ <a
88
+ href={buildNodeUrl(siteHome)}
89
+ aria-current={siteHome.getPath() === mainNode.getPath() ? 'page' : undefined}
90
+ >
91
+ {siteHome.getPropertyAsString('jcr:title') ?? siteHome.getName()}
92
+ </a>
93
+ </li>
94
+ {navPages.map(page => (
95
+ <li key={page.getPath()}>
96
+ <a
97
+ href={buildNodeUrl(page)}
98
+ aria-current={page.getPath() === mainNode.getPath() ? 'page' : undefined}
99
+ >
100
+ {page.getPropertyAsString('jcr:title') ?? page.getName()}
101
+ </a>
102
+ </li>
103
+ ))}
104
+ </ul>
105
+ </nav>
106
+ </header>
107
+ <main id="main-content">
108
+ <h1 className={styles.pageTitle}>{title}</h1>
109
+ <Area name="pagecontent" />
110
+ </main>
111
+ <footer className={styles.footer}>
112
+ <AbsoluteArea name="footer" parent={renderContext.getSite()} />
113
+ <p className={styles.copyright}>{'© '}{renderContext.getSite().getName()}</p>
114
+ </footer>
115
+ </body>
116
+ </html>
117
+ );
118
+ }
119
+ );
120
+ ```
121
+
122
+ Also create `src/templates/<ModuleName>Template/template.module.css` with minimal header/footer styles including `.skipLink` (visually hidden until focused), `.navList` (horizontal flex list), `.pageTitle`, and `.copyright`.
123
+
124
+ **Then, for each component** in the plan:
125
+
126
+ 1. Create `src/components/<Category>/<Name>/definition.cnd`
127
+ - **⚠️ This file only. Never add component types to `settings/definitions.cnd` — that file is for namespace declarations and the module base mixin only.**
128
+ - Namespace declarations at top (e.g. `<ns = 'https://example.com/ns/nt/1.0'>`)
129
+ - Extend `namespacemix:pageComponent` (for page-area components) or `namespacemix:component` (for children)
130
+ - Use `mix:title` for titles, NOT `- title (string)`
131
+ - Use `(weakreference, picker[type='image']) < jmix:image` for images
132
+ - Use `j:linkType (string, choicelist[linkTypeInitializer]) mandatory` for links
133
+ - Child items use `+ * (ns:childType) orderable`
134
+ - i18n on ALL user-visible string/textarea/richtext properties
135
+
136
+ **After writing the CND file, immediately run the checker and loop until clean:**
137
+
138
+ ```bash
139
+ CND_SCRIPT=$(find .claude .agents -name "check-cnd.mjs" 2>/dev/null | head -1)
140
+ [ -n "$CND_SCRIPT" ] && node "$CND_SCRIPT" src/components/<Category>/<Name>/definition.cnd
141
+ ```
142
+
143
+ - If the result is `FAIL`: read each issue, apply the fix, re-run.
144
+ - Repeat until the result is `PASS`.
145
+ - **Do not write the view (`types.ts`, `default.server.tsx`) until the CND is clean.**
146
+
147
+ 2. Create `src/components/<Category>/<Name>/types.ts`
148
+ - All props use `?:` (optional) even if mandatory in CND
149
+ - Import `JCRNodeWrapper` from `@jahia/javascript-modules-library` for node refs
150
+
151
+ 3. Create `src/components/<Category>/<Name>/default.server.tsx`
152
+ - Import `Props` from `./types.js`
153
+ - Use semantic HTML: `<section>`, `<article>`, `<header>`, `<main>`
154
+ - **Components use `<h2>` for their primary heading, `<h3>` for sub-headings. Never `<h1>` — the page template owns the h1.**
155
+ - Guard all props: `{prop?.value && <span>{prop.value}</span>}`
156
+ - Guard node URLs: `prop["j:linknode"] ? buildNodeUrl(prop["j:linknode"]) : "#"`
157
+ - `alt` on every `<img>`: use `imageAlt || title || 'Image'` — never fall back to empty string
158
+
159
+ 4. Create `src/components/<Category>/<Name>/component.module.css`
160
+ - Scoped CSS for the component
161
+ - Mobile-first responsive
162
+ - Colour contrast ≥ 4.5:1 for text on background
163
+
164
+ **After each component, deploy and verify it renders before moving to the next.**
165
+
166
+ **Check TypeScript types before each deploy:**
167
+
168
+ ```bash
169
+ tsc --noEmit 2>&1 | head -30
170
+ ```
171
+
172
+ Fix every type error before running `yarn build`. Use `mcp__ide__getDiagnostics` on each `.tsx` file for inline feedback — never grep `node_modules` for API signatures.
173
+
174
+ **Validate all CNDs before each deploy (final gate):**
175
+
176
+ ```bash
177
+ CND_SCRIPT=$(find .claude .agents -name "check-cnd.mjs" 2>/dev/null | head -1)
178
+ [ -n "$CND_SCRIPT" ] && node "$CND_SCRIPT" src/
179
+ ```
180
+
181
+ If the result is `FAIL`, fix every issue and re-run until `PASS`. Do not run `yarn build` until the checker is clean.
182
+
183
+ ---
184
+
185
+ ## Step 4 — Deploy
186
+
187
+ ```bash
188
+ yarn build && yarn jahia-deploy
189
+ ```
190
+
191
+ If it fails, read the error, fix it, and retry. Record the outcome.
192
+
193
+ ---
194
+
195
+ ## Step 5 — Create content (only if deploy succeeded)
196
+
197
+ Use MCP tools (the `jahia` MCP server) to:
198
+ 1. Discover the site key
199
+ 2. Create all pages as children of the home page (`parentPath: /sites/<key>/home`) — set `jcr:title` to the **short page name only** (e.g. "Car Insurance", not "Car Insurance | Acme Corp"). The template appends the site name to `<title>` automatically.
200
+ 3. Before creating content nodes, verify the parent area node exists with `content.get`. If it does not exist, create it first with the correct `jcr:primaryType` (e.g. `namespace:pageArea`).
201
+ 4. Create content nodes and populate them with realistic copy
202
+ 5. Publish all pages
203
+
204
+ **Verify every page renders real content and passes a11y + SEO checks:**
205
+
206
+ ```bash
207
+ SCRIPT=$(find .claude .agents -name "review-pages.mjs" 2>/dev/null | head -1)
208
+ node "$SCRIPT" 2>&1 | tee /tmp/site-review.txt
209
+ ```
210
+
211
+ The script checks each URL in `pages.json` for:
212
+ 1. HTTP 200 and no Jahia error markers
213
+ 2. A11y: no critical/serious WCAG 2.1 AA violations (axe-core)
214
+ 3. SEO: `<title>`, `<meta name="description">`, single `<h1>`, all `<img>` have `alt`
215
+
216
+ If the script exits 1, read the violations, fix them in the source, redeploy (`yarn build && yarn jahia-deploy`), and re-run. Do not write `pages.json` until the script exits 0.
217
+
218
+ **Tooling check** — if `review-pages.mjs` reports missing modules:
219
+ ```bash
220
+ npm install --no-save @axe-core/playwright playwright && npx playwright install chromium --with-deps
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Step 6 — Write pages.json
226
+
227
+ Only reach this step once every page verified clean in Step 5.
228
+
229
+ Collect the public URLs for all pages — URLs that return the full rendered page without requiring authentication. MCP tools often return edit/preview mode URLs; convert them to their publicly accessible equivalent before writing.
230
+
231
+ Write `pages.json`:
232
+ ```json
233
+ ["http://localhost:8080/cms/render/live/en/sites/<siteKey>/home.html", "..."]
234
+ ```
235
+
236
+ ---
237
+
238
+ ## Step 7 — Write DEV_STATUS.md
239
+
240
+ Write a `DEV_STATUS.md` file in the project root:
241
+
242
+ ```
243
+ # Dev Status
244
+
245
+ ## Status
246
+ COMPLETE
247
+
248
+ ## Components built
249
+ <list each component and whether CND + view + CSS were created>
250
+
251
+ ## Deploy
252
+ SUCCESS | FAILED — <error if failed>
253
+
254
+ ## Content
255
+ <number> pages created and published | SKIPPED | FAILED — <error>
256
+
257
+ ## pages.json written
258
+ YES | NO
259
+
260
+ ## Notes
261
+ <any issues, skipped items, or errors>
262
+ ```
263
+
264
+ Set Status to FAILED if deploy or content creation failed and could not be recovered.
@@ -0,0 +1,105 @@
1
+ ---
2
+ name: jahia-reviewer
3
+ description: Code review agent for Jahia modules. Reads the module source and writes REVIEW.md with findings from the jahia-dev-review criteria. Invoked by the orchestrator after each dev cycle.
4
+ allowed-tools: Read, Bash
5
+ # No tools: block — consistent with other agents; Claude Code allows all by default
6
+ ---
7
+
8
+ You are the Jahia code reviewer. Your job is to read the module source and report findings. You do NOT fix anything — you only report. Keep your analysis focused and your output concise.
9
+
10
+ ## Step 1 — Collect files to review
11
+
12
+ ```bash
13
+ find src/ -name "definition.cnd" | sort
14
+ find src/ -name "*.server.tsx" | sort
15
+ find src/ -name "types.ts" | sort
16
+ cat settings/definitions.cnd
17
+ ```
18
+
19
+ Read ALL of the above files before forming any conclusions.
20
+
21
+ ---
22
+
23
+ ## Step 2 — Run critical checks
24
+
25
+ Scan for each of these. Report only what you actually find — do not guess or infer.
26
+
27
+ ### 🔴 CRITICAL (must fix — causes broken pages or editor UX)
28
+
29
+ **C1** — Any concrete CND type (not a mixin) extending `jmix:droppableContent` directly
30
+ ```bash
31
+ grep -rn "jmix:droppableContent" src/ --include="*.cnd" | grep -v "mixin"
32
+ ```
33
+
34
+ **C2** — Page template not registered with `nodeType: "jnt:page"`
35
+ ```bash
36
+ grep -rn "componentType.*template" src/templates/ --include="*.server.tsx"
37
+ ```
38
+ Flag if any template file uses `componentType: 'template'` but does NOT have `nodeType: 'jnt:page'`. Page templates must always target `jnt:page` — a custom namespace type (e.g. `ns:template`) will never match and causes Jahia to render an error page.
39
+
40
+ Also flag: `fullPage` view with `componentType: "template"` (should be `componentType: "view"`).
41
+
42
+ **C3** — CND type explicitly declaring `j:linknode` or `j:url` fields
43
+ ```bash
44
+ grep -rn "j:linknode\|j:url" src/ --include="*.cnd"
45
+ ```
46
+
47
+ **C4** — View using `j:linkType` value directly as an `href`
48
+ ```bash
49
+ grep -rn 'href=.*j:linkType\|href=.*\["j:linkType"\]' src/ --include="*.server.tsx" --include="*.client.tsx"
50
+ ```
51
+ Note: a `switch(props["j:linkType"])` block is CORRECT usage — do NOT flag it. Only flag if the `j:linkType` value appears directly as an `href` attribute.
52
+
53
+ **C8** — All `<Area>` elements using the same generic `nodeType`
54
+ ```bash
55
+ grep -rn "nodeType" src/templates/ --include="*.server.tsx"
56
+ ```
57
+
58
+ ### 🟡 WARNINGS (fix if time allows)
59
+
60
+ **W1** — User-visible CND string/textarea without `i18n`
61
+ ```bash
62
+ grep -rn "(string\|textarea\|richtext)" src/ --include="*.cnd" | grep -v "i18n\|j:linkType\|j:url\|j:linknode"
63
+ ```
64
+
65
+ **W4** — Props typed as required (not `?:`) in types.ts
66
+ ```bash
67
+ grep -rn ": string\b\|: number\b\|: boolean\b" src/ --include="types.ts" | grep -v "?:"
68
+ ```
69
+
70
+ **W9** — Hardcoded URLs in views
71
+ ```bash
72
+ grep -rn 'href="http\|href="/\|href=`/' src/ --include="*.server.tsx" --include="*.client.tsx"
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Step 3 — Write REVIEW.md
78
+
79
+ Write `REVIEW.md` in the project root. Be specific: include file path and line content for each finding.
80
+
81
+ ```
82
+ # Code Review — Round <N>
83
+
84
+ ## Verdict
85
+ PASS | NEEDS_WORK
86
+
87
+ (PASS if zero Critical issues. NEEDS_WORK if any Critical issue found.)
88
+
89
+ ## Critical Issues (must fix before next deploy)
90
+ - [C1] src/components/Hero/definition.cnd:5 — extends jmix:droppableContent directly
91
+ Fix: change to extend namespacemix:pageComponent
92
+
93
+ (Write "None" if no critical issues.)
94
+
95
+ ## Warnings (fix if time allows, do NOT redeploy just for these)
96
+ ...
97
+
98
+ ## Suggestions (informational only)
99
+ ...
100
+
101
+ ## Summary
102
+ - Critical: N | Warnings: N | Suggestions: N
103
+ ```
104
+
105
+ Set Verdict to PASS only if there are **zero Critical issues**. Warnings and suggestions alone do not block.
@@ -7,15 +7,22 @@ You are helping develop a **Jahia JavaScript Module** — a React-based template
7
7
  ## Agent Principles
8
8
 
9
9
  1. **Always invoke a skill before any Jahia task** — skills are the canonical source of patterns, gotchas, and API syntax. Never operate from memory alone.
10
+ 1a. **Always load CND reference files before writing any CND** — Jahia-specific patterns (`choicelist[linkTypeInitializer]`, `mix:title`, child nodes for CTAs, `jmix:image` weakreferences) are not in your training data. Before writing any CND, read the reference files: `find . -maxdepth 4 -name 'cnd-jahia-mixins*' | head -3`. When working interactively through skill chains, prefer `@jahia-cnd-author` (it loads these files for you).
10
11
  2. **Never use `yarn dev` from an agent** — it is an interactive file watcher for human developers only. Always deploy with `yarn build && yarn jahia-deploy` (one-shot, non-interactive).
12
+ 2a. **Use the TypeScript LSP for API discovery, never grep.** When you need to know a function's signature or what a module exports, call `mcp__ide__getDiagnostics` on the file after writing it — the LSP reads live type definitions and reports mismatches, wrong argument counts, and missing exports. Never run `grep` on `node_modules` to find a function name or signature.
11
13
  3. **Never hardcode URLs** — all navigable links must come from contributed content (JCR nodes, `j:linkType`, `buildNodeUrl`). This is a CMS: content owns the URLs.
12
14
  4. **Never use `j:linkType: "external"` for internal pages** — use `"internal"` + `j:linknode`. External URLs break on environment changes, language switches, and vanity URL rewrites.
13
- 5. **Always verify before creating** — check that content types are deployed, site keys are correct, and area structures exist before attempting GraphQL mutations.
15
+ 5. **Always verify before creating** — check that content types are deployed, site keys are correct, and parent area nodes exist before creating content via MCP.
14
16
  6. **All props are optional at runtime** — even mandatory CND fields. Always guard against `undefined` in views.
15
- 7. **Always include `-H "Origin: http://localhost:8080"` in every GraphQL curl** omitting it returns `Permission denied` even with correct credentials.
16
- 8. **Build accessible HTML from the start** — every view must use semantic HTML (`<main>`, `<header>`, `<nav>`, `<footer>`, `<section>`, `<article>`), include exactly one `<h1>` per page, use a strict heading hierarchy (h1 → h2 → h3), add `alt` text to every `<img>`, and use sufficient colour contrast (≥ 4.5:1 for body text). Baking this in during authoring is faster than a post-hoc audit.
17
- 9. **Run one accessibility audit at the end** after all components are built and content is published, invoke `/jahia-dev-accessibility` once to catch any remaining violations. Do not audit after every individual component; it wastes time on pages that are not yet complete.
18
- 10. **Batch builds and deploys** — build all components together, then run `yarn build && yarn jahia-deploy` once rather than after each individual component. Deploy once before populating content.
17
+ 7. **Use MCP tools for all Jahia operations — never GraphQL curl.** The `jahia` MCP server covers site, page, content, and publication operations. Never fall back to `curl` + GraphQL mutations for anything the MCP server can do. Never write Python scripts — use JavaScript or bash only.
18
+ 7a. **`yarn` and `npx` must be run from the module root** — the module is a standalone project, not part of a monorepo. Running `yarn` from a parent directory fails with a workspace boundary error. Always `cd` to the module directory first.
19
+ 7b. **Use `grep`, not `ugrep`** `ugrep` is not available on all systems and does not support the same regex syntax. Use `grep -rn` for plain text, `grep -rn -E` for extended regex, or `grep -rn -P` for Perl-compatible patterns (e.g. lookaheads). Never use `ugrep` or `(?m)` flags.
20
+ 8. **Build accessible HTML from the start** — every view must use semantic HTML (`<main>`, `<header>`, `<nav>`, `<footer>`, `<section>`, `<article>`), include exactly one `<h1>` per page (in the template from `jcr:title` never inside a component), use a strict heading hierarchy (h1 in template → h2 in components → h3 for sub-items), add `alt` text to every `<img>` with a meaningful fallback (`imageAlt || title || 'Image'` — never empty string), ensure sufficient colour contrast (≥ 4.5:1 for body text), include a skip link at the top of the template, and never leave a landmark (`<nav>`, `<footer>`) empty.
21
+ 9. **Review quality after each deploy** — after deploying and populating content, run `/jahia-dev-site-review` to get a scored a11y + SEO report. Fix any critical/serious violations before moving on. Do not write `pages.json` until the review passes.
22
+ 10. **Deploy iteratively** — deploy after each component with `yarn build && yarn jahia-deploy`, verify it renders, then move to the next. Don't accumulate components before deploying; a broken component is easier to diagnose in isolation.
23
+ 11. **Collocate everything per component** — each component lives in `src/components/<Category>/<Name>/` containing its `definition.cnd`, `default.server.tsx`, `component.module.css`, and `types.ts`. Never centralize content types in `settings/definitions.cnd` — that file holds only namespace declarations and the module base mixin.
24
+ 12. **Always build a page template first** — every website needs a root template at `src/templates/<ModuleName>Template/default.server.tsx`. It must include: a skip link, a `<nav>` built inline from children of the site's home node using `getChildNodes(renderContext.getSite().getNode('home'), -1, 0, n => n.isNodeType('jnt:page'))` (pages live under `home`, not directly under the site), a `<main id="main-content">` with `<h1>{title}</h1>` and Areas, and a `<footer>` that is never empty. The `<title>` tag must be `{title} | {siteName}` — never set `jcr:title` to the full `Page | Site` string; `jcr:title` is always just the short page name (e.g. "Car Insurance"). Build and deploy before any page-specific components.
25
+ 13. **SEO baseline** — every page template must render a `<title>` tag, all `<img>` must have descriptive `alt` text, all links must have visible text (no icon-only links without `aria-label`), and pages must have a single `<h1>` matching the page title.
19
26
 
20
27
  ## Skill Map
21
28
 
@@ -30,11 +37,13 @@ Start with `/jahia` if unsure where to begin.
30
37
  | `/jahia-dev-start-local` | Start Jahia locally (Docker or bare metal) |
31
38
  | `/jahia-dev-build-component` | Build a complete component (CND + view) — start here |
32
39
  | `/jahia-dev-define-content-type` | Define a CND content type + types.ts |
40
+ | `/jahia-dev-review-cnd` | Validate a CND file for antipatterns — run after writing any CND |
33
41
  | `/jahia-dev-create-view` | Implement a React view (.server.tsx + CSS Module) |
34
42
  | `/jahia-dev-create-page-template` | Create a page template with Areas |
35
43
  | `/jahia-dev-query-content` | Write JCR-SQL2 queries and useJCRQuery |
36
44
  | `/jahia-dev-review` | Code review: 8 critical checks, 9 warnings, 11 suggestions |
37
- | `/jahia-dev-accessibility` | Audit live pages with axe-core, fix WCAG 2.1 AA violations |
45
+ | `/jahia-dev-site-review` | Scored a11y + SEO report on live pages use after every deploy |
46
+ | `/jahia-dev-accessibility` | Deep WCAG 2.1 AA audit with fixes — use for targeted a11y work |
38
47
  | `/jahia-dev-screenshot` | Screenshot reference + local render for visual comparison |
39
48
  | `/jahia-dev-debug` | Debug build/deploy/runtime errors end-to-end |
40
49
 
@@ -88,7 +88,11 @@ Use these recipes as starting points when the task maps to a known pattern.
88
88
  ```
89
89
  1. /jahia-dev-create-template-set → scaffold the module
90
90
  2. /jahia-dev-start-local → start Jahia locally
91
- 3. /jahia-dev-build-component → build content types + views (repeat per component)
91
+ 3. /jahia-dev-build-component → build ONE component at a time (repeat this step per component):
92
+ - invokes /jahia-dev-define-content-type
93
+ - which invokes @jahia-cnd-author (sub-agent, mandatory)
94
+ - then invokes /jahia-dev-create-view
95
+ ⚠ Never batch-write CND — always go through @jahia-cnd-author
92
96
  4. /jahia-dev-create-page-template → create page templates
93
97
  5. /jahia-content-create-content → use `site.templateSets` + `site.create`, then add pages and content
94
98
  6. /jahia-content-publish → publish the site content
@@ -110,10 +110,10 @@ color: #595959; /* 7:1 ratio on white */
110
110
  /* Bad */
111
111
  <img src={buildNodeUrl(props.image)} />
112
112
 
113
- /* Fix — use content from CND, fall back to empty string for decorative */
114
- <img src={buildNodeUrl(props.image)} alt={props.imageAlt ?? ""} />
113
+ /* Fix — use the image node's jcr:title, fall back to empty string for decorative */
114
+ <img src={buildNodeUrl(props.image)} alt={props.image?.getPropertyAsString("jcr:title") ?? ""} />
115
115
  ```
116
- Add `- imageAlt (string) i18n` to the CND and `imageAlt?: string` to `types.ts`.
116
+ The image node already has `jcr:title` (from `mix:title`). **Do not add `imageAlt (string) i18n`** to the CND.
117
117
 
118
118
  **`button-name`** — `<button>` or `<a>` is empty (icon-only without label)
119
119
  ```tsx
@@ -43,15 +43,18 @@ Has children: <yes: ChildType / no>
43
43
 
44
44
  ---
45
45
 
46
- ## Step 2 — Invoke `jahia-dev-define-content-type`
46
+ ## Step 2 — REQUIRED: Invoke `/jahia-dev-define-content-type`
47
47
 
48
- Use the instructions from the `jahia-dev-define-content-type` skill to:
48
+ **Do not write CND manually.** Jahia-specific patterns (`choicelist[linkTypeInitializer]`, `mix:title`, child nodes for CTAs) are not in LLM training data — writing CND from memory always produces broken output. This skill delegates to `@jahia-cnd-author` which loads the correct reference files.
49
49
 
50
- 1. Identify the namespace (check `settings/definitions.cnd`)
51
- 2. Create `src/components/<Category>/<Name>/definition.cnd`
52
- 3. Create `src/components/<Category>/<Name>/types.ts`
53
- 4. Run `yarn build && yarn jahia-deploy` to push the type to Jahia
54
- 5. Verify the content type appears in the Jahia content editor
50
+ Invoke `/jahia-dev-define-content-type` in a sub-agent job. Pass the component spec. Wait for it to confirm PASS before continuing.
51
+
52
+ The skill will:
53
+ 1. Confirm the namespace (from `settings/definitions.cnd`)
54
+ 2. Invoke `@jahia-cnd-author` to create `src/components/<Category>/<Name>/definition.cnd`
55
+ 3. Invoke `@jahia-cnd-author` to create `src/components/<Category>/<Name>/types.ts`
56
+
57
+ **Do not proceed to Step 3 until the CND review is PASS.**
55
58
 
56
59
  ---
57
60
 
@@ -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