@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,59 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync } from "node:fs";
3
+ import { execSync } from "node:child_process";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+
7
+ const pagesFile = "pages.json";
8
+ let urls;
9
+ try {
10
+ urls = JSON.parse(readFileSync(pagesFile, "utf8"));
11
+ } catch {
12
+ console.error(`MISSING: ${pagesFile} not found or invalid JSON`);
13
+ process.exit(1);
14
+ }
15
+
16
+ if (!Array.isArray(urls) || urls.length === 0) {
17
+ console.error(`EMPTY: ${pagesFile} contains no URLs`);
18
+ process.exit(1);
19
+ }
20
+
21
+ const tmp = join(tmpdir(), "jahia_pg_verify.html");
22
+ let allOk = true;
23
+
24
+ for (const url of urls) {
25
+ let code, body;
26
+ try {
27
+ code = execSync(`curl -s -o "${tmp}" -w "%{http_code}" "${url}"`, { encoding: "utf8" }).trim();
28
+ body = readFileSync(tmp, "utf8");
29
+ } catch {
30
+ console.log(`ERROR [unknown] ${url}`);
31
+ allOk = false;
32
+ continue;
33
+ }
34
+ const titleMatch = body.match(/<title>([^<]*)<\/title>/i);
35
+ const title = titleMatch ? titleMatch[1].trim() : "";
36
+ const hasError =
37
+ body.includes("error details are shown in development mode") ||
38
+ body.includes("pl.touk.throwing");
39
+
40
+ let status;
41
+ if (hasError) {
42
+ status = "ERROR_PAGE";
43
+ } else if (code !== "200") {
44
+ status = `HTTP_${code}`;
45
+ } else {
46
+ const mainMatch = body.match(/<main[^>]*>([\s\S]*?)<\/main>/i);
47
+ if (mainMatch) {
48
+ const mainText = mainMatch[1].replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
49
+ status = mainText.length < 150 ? "INCOMPLETE" : "OK";
50
+ } else {
51
+ status = "OK";
52
+ }
53
+ }
54
+
55
+ console.log(`${status} [${title}] ${url}`);
56
+ if (status !== "OK") allOk = false;
57
+ }
58
+
59
+ process.exit(allOk ? 0 : 1);
@@ -0,0 +1,74 @@
1
+ # CND Child Nodes
2
+
3
+ ## Syntax
4
+
5
+ ```cnd
6
+ + childName (ns:type) // named child — exactly one
7
+ + childName (ns:type) multiple // named child — list
8
+ + * (ns:type) // any-name child of a specific type
9
+ + * (jmix:droppableContent) // open container — any droppable component
10
+ ```
11
+
12
+ ## When to use child nodes vs `weakreference multiple`
13
+
14
+ | Use child nodes when… | Use `weakreference multiple` when… |
15
+ |---|---|
16
+ | Each item has multiple properties (label + link) | Each item is just a reference (a page, an image) |
17
+ | Items have no life outside the parent | Items are managed elsewhere and reused |
18
+ | You always create them together | Editors need to pick from existing content |
19
+
20
+ ## Repeatable CTA pattern
21
+
22
+ **NEVER put `ctaText + ctaLink/ctaUrl` on the parent type as flat properties.**
23
+ Model CTAs as child nodes — editors can then add multiple CTAs.
24
+
25
+ ```cnd
26
+ // ✅ Correct — supports multiple CTAs
27
+ [ns:heroSection] > jnt:content, nsmix:component, mix:title
28
+ - subtitle (string, richtext) i18n
29
+ - backgroundImage (weakreference, picker[type='image']) < jmix:image
30
+ + * (ns:heroCallToAction)
31
+
32
+ [ns:heroCallToAction] > jnt:content, nsmix:component
33
+ - label (string) i18n mandatory
34
+ - j:linkType (string, choicelist[linkTypeInitializer]) mandatory
35
+
36
+ // ❌ Wrong — forces exactly one CTA, editors can't add more
37
+ [ns:heroSection] > jnt:content, nsmix:component
38
+ - ctaText (string) i18n
39
+ - ctaLink (string) i18n // also wrong type for links
40
+ ```
41
+
42
+ ## Ordering
43
+
44
+ Add `orderable` to the parent type when editors need to reorder children:
45
+
46
+ ```cnd
47
+ [ns:featureList] > jnt:content, nsmix:component orderable
48
+ + * (ns:featureItem)
49
+ ```
50
+
51
+ ## Hidden structural nodes
52
+
53
+ Child nodes that editors should never add manually (structural containers, auto-created nodes):
54
+
55
+ ```cnd
56
+ [ns:heroSection] > jnt:content, nsmix:component, mix:title
57
+ + ctaContainer (ns:ctaContainer) autocreated
58
+
59
+ [ns:ctaContainer] > jnt:content, jmix:hiddenType orderable
60
+ + * (ns:callToAction)
61
+ ```
62
+
63
+ `jmix:hiddenType` hides a type from the Page Builder component picker.
64
+ **Never use `jmix:studioOnly`** — it causes silent rendering issues.
65
+
66
+ ## Open container (accept any droppable)
67
+
68
+ ```cnd
69
+ [ns:gridRow] > jnt:content, nsmix:component
70
+ - columns (long) = '3' autocreated mandatory < '1', '2', '3', '4'
71
+ + * (jmix:droppableContent)
72
+ ```
73
+
74
+ `+ * (jmix:droppableContent)` accepts any component the editor can drop.
@@ -0,0 +1,113 @@
1
+ # Jahia Native Mixins & Types
2
+
3
+ Source: https://github.com/Jahia/jahia/tree/master/war/src/main/webapp/WEB-INF/etc/repository/nodetypes
4
+ Fetch this URL to verify before using any mixin not listed here.
5
+
6
+ ## Base types — always extend these
7
+
8
+ | Type | Purpose |
9
+ |---|---|
10
+ | `jnt:content` | Base for all user content nodes — **always include** |
11
+ | `jnt:page` | Page node — only for `jmix:mainResource` full-page types |
12
+ | `jnt:file` | File node — for file references |
13
+
14
+ ## Mixins by use case
15
+
16
+ ### `mix:title` — preferred over a raw title property
17
+
18
+ Adds `jcr:title` (string). Jahia's UI, breadcrumbs, SEO, and sitemap generation all read `jcr:title`.
19
+ **Extend this instead of declaring `- title (string) i18n mandatory`.**
20
+
21
+ ```cnd
22
+ [ns:article] > jnt:content, nsmix:component, mix:title
23
+ ```
24
+
25
+ Access in view: `props["jcr:title"]`
26
+
27
+ ### `jmix:mainResource` — full-page content types only
28
+
29
+ Makes a node accessible at its own URL. Use **only** for content that needs both a listing card AND a detail page (e.g. blog posts, team members, events). Do not add to navigation or visual composition types.
30
+
31
+ ```cnd
32
+ [ns:blogPost] > jnt:content, mix:title, jmix:mainResource, nsmix:component
33
+ ```
34
+
35
+ ### `jmix:image` — image constraint for weakreference
36
+
37
+ Use as the type constraint on image weakreference properties:
38
+
39
+ ```cnd
40
+ - backgroundImage (weakreference, picker[type='image']) < jmix:image
41
+ ```
42
+
43
+ **Never use `< 'jnt:file'`** (quoted string form) — it does not enforce image type correctly.
44
+
45
+ **Never declare `imageAlt (string) i18n`** alongside an image weakreference. The referenced image node already has `jcr:title` (from `mix:title`). Use that as the alt text in the view:
46
+
47
+ ```tsx
48
+ const imageAlt = props.image?.getPropertyAsString("jcr:title") ?? "";
49
+ ```
50
+
51
+ Remove any `imageAlt` property — it forces editors to enter duplicate data.
52
+
53
+ ### `jmix:droppableContent` — never extend directly
54
+
55
+ Always define a module-level component mixin and extend that:
56
+
57
+ ```cnd
58
+ // In settings/definitions.cnd
59
+ [nsmix:component] > jmix:droppableContent, jmix:accessControllableContent mixin
60
+ ```
61
+
62
+ Then all component types extend `nsmix:component`.
63
+
64
+ ### `jmix:hiddenType` — hide from Page Builder picker
65
+
66
+ Structural/container types editors should not add manually:
67
+
68
+ ```cnd
69
+ [ns:ctaContainer] > jnt:content, jmix:hiddenType orderable
70
+ ```
71
+
72
+ **Never use `jmix:studioOnly`** — it causes silent rendering issues in some contexts.
73
+
74
+ ### `jmix:accessControllableContent` — per-component access control
75
+
76
+ Add to your base module mixin so all components support it:
77
+
78
+ ```cnd
79
+ [nsmix:component] > jmix:droppableContent, jmix:accessControllableContent mixin
80
+ ```
81
+
82
+ ### `jmix:link` — built-in link type
83
+
84
+ Provides `j:linkType`, `j:linknode`, `j:url`, `j:linkTitle`. Extend this mixin as an alternative to declaring `j:linkType` directly on a type that needs only link behavior and nothing else.
85
+
86
+ ## picker[] selector
87
+
88
+ | Selector | Use |
89
+ |---|---|
90
+ | `picker[type='image']` | Image assets only |
91
+ | `picker[type='file']` | Any file asset |
92
+
93
+ ```cnd
94
+ - backgroundImage (weakreference, picker[type='image']) < jmix:image
95
+ - attachment (weakreference, picker[type='file']) < jnt:file
96
+ ```
97
+
98
+ ## Two-tier component mixin system
99
+
100
+ If the module uses custom area types (see `jahia-dev-create-page-template`):
101
+
102
+ ```cnd
103
+ [nsmix:component] > jmix:droppableContent, jmix:accessControllableContent mixin
104
+ [nsmix:pageComponent] > nsmix:component mixin
105
+ ```
106
+
107
+ | Component will be… | Extend |
108
+ |---|---|
109
+ | Dropped in page areas | `nsmix:pageComponent` |
110
+ | Child of another component | `nsmix:component` |
111
+ | Listed programmatically | `nsmix:component` |
112
+
113
+ A component extending only `nsmix:component` **cannot** be dropped in areas that use `nsmix:pageComponent`.
@@ -0,0 +1,61 @@
1
+ # CND Numeric, Date & Boolean Properties
2
+
3
+ ## Types
4
+
5
+ | Type | Editor widget | Notes |
6
+ |---|---|---|
7
+ | `long` | Integer number input | Counts, limits, columns |
8
+ | `double` | Decimal number input | Coordinates, prices, ratios |
9
+ | `boolean` | Checkbox | Feature flags, toggles |
10
+ | `date` | Date picker | ISO 8601 stored, string in TypeScript |
11
+ | `date, datepicker` | Date + time picker | Same storage, richer widget |
12
+
13
+ ## Default values with `autocreated`
14
+
15
+ Always combine `autocreated` with `= 'value'`:
16
+
17
+ ```cnd
18
+ - columns (long) = '3' autocreated mandatory < '1', '2', '3', '4'
19
+ - isHighlighted (boolean) = 'false' autocreated
20
+ - country (string, choicelist[country]) = 'US' autocreated mandatory
21
+ ```
22
+
23
+ ## Range constraints
24
+
25
+ ```cnd
26
+ // Numeric range — inclusive brackets
27
+ - latitude (double) mandatory < "[-90,90]"
28
+ - longitude (double) mandatory < "[-180,180]"
29
+ - rating (long) mandatory < "[1,5]"
30
+ ```
31
+
32
+ **Star ratings always need a range constraint.** Never write `rating (long)` without `< "[1,5]"`:
33
+
34
+ ```cnd
35
+ // WRONG
36
+ - rating (long) = 5 indexed=no
37
+
38
+ // CORRECT
39
+ - rating (long) = '3' autocreated mandatory < "[1,5]"
40
+ ```
41
+
42
+ ## Date range constraints
43
+
44
+ Parentheses = exclusive bound, brackets = inclusive. Leave a side empty for open-ended:
45
+
46
+ ```cnd
47
+ // Any date after 2020-01-01 (exclusive)
48
+ - eventDate (date, datepicker) < '(2020-01-01T00:00:00.000,)'
49
+
50
+ // Bounded campaign window
51
+ - campaignDate (date, datepicker) < '(2020-01-01T00:00:00.000,2030-12-31T00:00:00.000)'
52
+ ```
53
+
54
+ ## TypeScript mapping
55
+
56
+ | CND type | TypeScript |
57
+ |---|---|
58
+ | `long` | `number` |
59
+ | `double` | `number` |
60
+ | `boolean` | `boolean` |
61
+ | `date` | `string` (ISO 8601) |
@@ -0,0 +1,94 @@
1
+ # CND String & Selector Properties
2
+
3
+ ## String type variants
4
+
5
+ | Type declaration | Editor widget | When to use |
6
+ |---|---|---|
7
+ | `(string)` | Single-line text input | Short labels, IDs, slugs |
8
+ | `(string, textarea)` | Multi-line text area | Paragraphs, descriptions |
9
+ | `(string, richtext)` | Rich text editor (TinyMCE) | Body content, formatted text |
10
+ | `(string) multiple` | Tag input / list | Lists of plain strings |
11
+
12
+ ## Fixed-choice dropdowns
13
+
14
+ Use `(string, choicelist)` + `< 'val1', 'val2'` for a dropdown with a hard-coded list.
15
+ **Never use `choicelist[val1,val2]`** — the bracket syntax is for initializer keywords, not values.
16
+
17
+ ```cnd
18
+ - difficulty (string, choicelist) i18n < 'beginner', 'intermediate', 'advanced'
19
+ - variant (string, choicelist) < 'primary', 'secondary', 'ghost'
20
+ ```
21
+
22
+ ## `mix:title` instead of a title string property
23
+
24
+ **NEVER write `- title (string) i18n mandatory`.**
25
+ Extend `mix:title` instead — it adds `jcr:title`, which Jahia's UI, breadcrumbs, and search use natively.
26
+
27
+ ```cnd
28
+ // ✅ Correct
29
+ [ns:heroSection] > jnt:content, nsmix:component, mix:title
30
+
31
+ // ❌ Wrong — duplicates what mix:title already provides
32
+ [ns:heroSection] > jnt:content, nsmix:component
33
+ - title (string) i18n mandatory
34
+ ```
35
+
36
+ Access in the view as `props["jcr:title"]`.
37
+
38
+ ## Link picker — `choicelist[linkTypeInitializer]`
39
+
40
+ **NEVER use `(string)` for a link, URL, href, or path.**
41
+ Use `choicelist[linkTypeInitializer]` — it renders an internal/external/none picker in the editor.
42
+
43
+ **Declare ONLY `j:linkType` in the CND. Do NOT add `j:linknode` or `j:url` — Jahia injects them automatically.**
44
+
45
+ ```cnd
46
+ // ✅ Correct — bare minimum
47
+ [ns:callToAction] > jnt:content, nsmix:component
48
+ - label (string) i18n mandatory
49
+ - j:linkType (string, choicelist[linkTypeInitializer]) mandatory
50
+
51
+ // ❌ Wrong — do not declare companion fields
52
+ - j:linknode (weakreference) // injected by Jahia — remove this
53
+ - j:url (string) // injected by Jahia — remove this
54
+ ```
55
+
56
+ TypeScript discriminated union for the view:
57
+
58
+ ```ts
59
+ import type { JCRNodeWrapper } from "org.jahia.services.content";
60
+ export type Props =
61
+ | { label?: string; "j:linkType": "none" }
62
+ | { label?: string; "j:linkType": "internal"; "j:linknode"?: JCRNodeWrapper }
63
+ | { label?: string; "j:linkType": "external"; "j:url"?: string; "j:linkTitle"?: string };
64
+ ```
65
+
66
+ In the view, switch on `props["j:linkType"]`.
67
+
68
+ ## Other `choicelist[...]` initializers
69
+
70
+ | Initializer | What it renders |
71
+ |---|---|
72
+ | `choicelist[country]` | Country selector (ISO codes, localized labels) |
73
+ | `choicelist[resourceBundle]` | Labels from `.properties` file keys |
74
+ | `choicelist[nodes=/path;type=jnt:content]` | Nodes under a JCR path |
75
+ | `choicelist[componentTypes=jnt:page]` | Registered views of a node type |
76
+ | `choicelist[menus]` | Site menus |
77
+
78
+ ## Regex constraints on strings
79
+
80
+ ```cnd
81
+ - contactEmail (string) < '^$|[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}'
82
+ - slug (string) < '^[a-z0-9-]+$'
83
+ - externalUrl (string) < '^https?://'
84
+ ```
85
+
86
+ ## Common attributes
87
+
88
+ | Attribute | Meaning |
89
+ |---|---|
90
+ | `i18n` | Translatable per language — **default to always on user-facing fields** |
91
+ | `mandatory` | Required |
92
+ | `multiple` | List of values |
93
+ | `primary` | Highlighted field in editor (one per type) |
94
+ | `autocreated` | Auto-created on node creation — always combine with `= 'defaultValue'` |
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: jahia-cnd-author
3
+ description: Use when you need to write a Jahia CND content type definition and its TypeScript props interface. Receives a component spec and produces a per-component definition.cnd + types.ts with correct Jahia-specific syntax. Self-validates output before returning.
4
+ allowed-tools: Read, Write, Edit, Bash
5
+ tools:
6
+ Read: true
7
+ Write: true
8
+ Edit: true
9
+ Bash: true
10
+ ---
11
+
12
+ You are a Jahia CND specialist. Your sole job is to write correct `definition.cnd` and `types.ts` files for a single component type. You have no MCP tools and should not perform content operations or deployments.
13
+
14
+ ## Your inputs
15
+
16
+ You will receive a structured spec:
17
+
18
+ ```
19
+ Component: <name>
20
+ Namespace prefix: <ns>
21
+ Module path: <path to module root>
22
+ Fields:
23
+ - <field name>: <type description> [mandatory] [i18n] [multiple]
24
+ Usage: <where this component appears>
25
+ Children: <repeatable sub-items if any>
26
+ ```
27
+
28
+ ## Step 1 — Locate and load reference files
29
+
30
+ Reference files live next to this agent file. First, discover where they are:
31
+
32
+ ```bash
33
+ # Find the directory that contains the cnd-jahia-mixins reference file
34
+ find . -maxdepth 4 -name "cnd-jahia-mixins*" 2>/dev/null | head -5
35
+ ```
36
+
37
+ Then read the files you need (using whichever path the find command returned):
38
+
39
+ - **Always read**: `cnd-jahia-mixins` (required — tells you which native mixins to extend)
40
+ - **If text, link, or choice properties**: `cnd-string-selectors`
41
+ - **If repeatable child items**: `cnd-child-nodes`
42
+ - **If numbers, dates, or booleans**: `cnd-numbers-dates`
43
+
44
+ Do not skip this step. These files contain the exact CND patterns you must use. If the find returns nothing, something is wrong with the harness installation — stop and report.
45
+
46
+ ## Step 2 — Resolve namespace and location
47
+
48
+ ```bash
49
+ # Get namespace prefix
50
+ grep "^<" <module-path>/settings/definitions.cnd | head -5
51
+
52
+ # Check for two-tier mixin
53
+ grep "pageComponent" <module-path>/settings/definitions.cnd
54
+
55
+ # Find the right category directory
56
+ ls <module-path>/src/components/
57
+ ```
58
+
59
+ If `namespacemix:pageComponent` exists: use it for components dropped in page areas, use `namespacemix:component` for children of other components.
60
+
61
+ **File locations — collocation is mandatory:**
62
+
63
+ Each component type lives in its own file, next to its view. NEVER put all types in `settings/definitions.cnd`.
64
+
65
+ ```
66
+ src/
67
+ components/
68
+ Sections/
69
+ HeroSection/
70
+ definition.cnd ← one type per file, co-located here
71
+ default.server.tsx
72
+ types.ts
73
+ Cards/
74
+ TextCard/
75
+ definition.cnd ← separate file per component
76
+ types.ts
77
+ settings/
78
+ definitions.cnd ← namespace declarations + shared mixins ONLY
79
+ ```
80
+
81
+ ## Step 3 — Write the CND
82
+
83
+ Create `<module-path>/src/components/<Category>/<Name>/definition.cnd`.
84
+
85
+ Rules from the reference files you loaded — apply all of them:
86
+ 1. **Links**: `j:linkType (string, choicelist[linkTypeInitializer]) mandatory` — never `(string)` for `*Url`, `*Href`, `*Link`
87
+ 2. **Titles**: extend `mix:title` — never `- title (string)` or `- jcr:title (string)`
88
+ 3. **Repeatable CTAs**: child nodes `+ * (ns:callToAction)` — never flat `ctaText + ctaUrl` on the parent
89
+ 4. **Images**: `(weakreference, picker[type='image']) < jmix:image` — never `(string)` for image URLs
90
+ 5. **i18n**: on every user-facing string/textarea/richtext property
91
+ 6. **Component mixin**: extend `namespacemix:component` or `namespacemix:pageComponent` — never `jmix:droppableContent` directly on a concrete type
92
+
93
+ Each per-component `definition.cnd` must include the namespace declarations at the top:
94
+ ```cnd
95
+ <ns = 'http://...'>
96
+ <nsmix = 'http://...'>
97
+ ```
98
+
99
+ ## Step 4 — Write types.ts
100
+
101
+ Create `<module-path>/src/components/<Category>/<Name>/types.ts`. All fields use `?:` even if mandatory in CND.
102
+
103
+ For `j:linkType` properties, use the discriminated union from the reference file you loaded.
104
+
105
+ ## Step 5 — Self-validate
106
+
107
+ ```bash
108
+ CND=<module-path>/src/components/<Category>/<Name>/definition.cnd
109
+
110
+ # Error: raw string for a link/URL property
111
+ grep -En "^[[:space:]]*-[[:space:]]+[a-zA-Z]*(Url|Href|Link)[[:space:]]+\(string" "$CND"
112
+
113
+ # Error: title declared as raw property instead of mix:title
114
+ grep -En "^[[:space:]]*-[[:space:]]+(title|jcr:title)[[:space:]]+\(string" "$CND"
115
+
116
+ # Error: concrete type extends jmix:droppableContent directly
117
+ grep -n "jmix:droppableContent" "$CND" | grep -v "mixin"
118
+
119
+ # Error: image as plain string URL
120
+ grep -En "^[[:space:]]*-[[:space:]]+[a-zA-Z]*(Image|Photo|Avatar|Logo)[[:space:]]+\(string" "$CND"
121
+ ```
122
+
123
+ If any of these print matches, fix the issue and re-run before reporting.
124
+
125
+ ## Step 6 — Report
126
+
127
+ - Files written: paths
128
+ - Type name(s) defined
129
+ - Self-validate result: PASS / fixed N errors
130
+ - Any warnings not fixed and why