@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.
- package/CHANGELOG.md +4 -0
- package/dist/claude/.claude/agents/cnd-child-nodes.md +74 -0
- package/dist/claude/.claude/agents/cnd-jahia-mixins.md +113 -0
- package/dist/claude/.claude/agents/cnd-numbers-dates.md +61 -0
- package/dist/claude/.claude/agents/cnd-string-selectors.md +94 -0
- package/dist/claude/.claude/agents/jahia-cnd-author.md +130 -0
- package/dist/claude/.claude/agents/jahia-dev-worker.md +264 -0
- package/dist/claude/.claude/agents/jahia-reviewer.md +105 -0
- package/dist/claude/.claude/rules/jahia.md +15 -6
- package/dist/claude/.claude/skills/jahia/SKILL.md +5 -1
- package/dist/claude/.claude/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/claude/.claude/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/claude/.claude/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/claude/.claude/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/claude/.claude/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/claude/.claude/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/claude/.claude/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/claude/.claude/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/claude/.claude/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/claude/.claude/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/claude/.claude/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/claude/.claude/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/claude/.claude/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/claude/CLAUDE.md +16 -7
- package/dist/codex/.agents/skills/jahia/SKILL.md +5 -1
- package/dist/codex/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/codex/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/codex/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/codex/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/codex/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/codex/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/codex/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/codex/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/codex/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/codex/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/codex/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/codex/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/codex/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/codex/.codex/agents/cnd-child-nodes.toml +3 -0
- package/dist/codex/.codex/agents/cnd-jahia-mixins.toml +3 -0
- package/dist/codex/.codex/agents/cnd-numbers-dates.toml +3 -0
- package/dist/codex/.codex/agents/cnd-string-selectors.toml +3 -0
- package/dist/codex/.codex/agents/jahia-cnd-author.toml +3 -0
- package/dist/codex/.codex/agents/jahia-dev-worker.toml +3 -0
- package/dist/codex/.codex/agents/jahia-reviewer.toml +3 -0
- package/dist/codex/AGENTS.md +17 -8
- package/dist/copilot/.agents/skills/jahia/SKILL.md +5 -1
- package/dist/copilot/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/copilot/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/copilot/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/copilot/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/copilot/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/copilot/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/copilot/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/copilot/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/copilot/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/copilot/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/copilot/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/copilot/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/copilot/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/copilot/AGENTS.md +17 -8
- package/dist/cursor/.agents/skills/jahia/SKILL.md +5 -1
- package/dist/cursor/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/cursor/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/cursor/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/cursor/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/cursor/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/cursor/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/cursor/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/cursor/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/cursor/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/cursor/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/cursor/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/cursor/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/cursor/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/cursor/.cursor/agents/cnd-child-nodes.md +74 -0
- package/dist/cursor/.cursor/agents/cnd-jahia-mixins.md +113 -0
- package/dist/cursor/.cursor/agents/cnd-numbers-dates.md +61 -0
- package/dist/cursor/.cursor/agents/cnd-string-selectors.md +94 -0
- package/dist/cursor/.cursor/agents/jahia-cnd-author.md +130 -0
- package/dist/cursor/.cursor/agents/jahia-dev-worker.md +264 -0
- package/dist/cursor/.cursor/agents/jahia-reviewer.md +105 -0
- package/dist/cursor/.cursor/rules/jahia.mdc +15 -6
- package/dist/gemini/.agents/skills/jahia/SKILL.md +5 -1
- package/dist/gemini/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/gemini/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/gemini/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/gemini/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/gemini/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/gemini/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/gemini/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/gemini/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/gemini/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/gemini/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/gemini/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/gemini/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/gemini/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/gemini/AGENTS.md +17 -8
- package/dist/gemini/GEMINI.md +2 -2
- package/dist/index.js +13 -0
- package/dist/opencode/.agents/skills/jahia/SKILL.md +5 -1
- package/dist/opencode/.agents/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/opencode/.agents/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/opencode/.agents/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/opencode/.agents/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/opencode/.agents/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/opencode/.agents/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/opencode/.agents/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/opencode/.agents/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/opencode/.agents/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/opencode/.agents/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/opencode/.agents/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/opencode/.agents/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/opencode/.agents/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/opencode/.opencode/agents/cnd-child-nodes.md +74 -0
- package/dist/opencode/.opencode/agents/cnd-jahia-mixins.md +113 -0
- package/dist/opencode/.opencode/agents/cnd-numbers-dates.md +61 -0
- package/dist/opencode/.opencode/agents/cnd-string-selectors.md +94 -0
- package/dist/opencode/.opencode/agents/jahia-cnd-author.md +130 -0
- package/dist/opencode/.opencode/agents/jahia-dev-worker.md +264 -0
- package/dist/opencode/.opencode/agents/jahia-reviewer.md +105 -0
- package/dist/opencode/AGENTS.md +17 -8
- package/dist/windsurf/.windsurf/rules/jahia.md +15 -6
- package/dist/windsurf/.windsurf/skills/jahia/SKILL.md +5 -1
- package/dist/windsurf/.windsurf/skills/jahia-dev-accessibility/SKILL.md +3 -3
- package/dist/windsurf/.windsurf/skills/jahia-dev-build-component/SKILL.md +10 -7
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-page-template/SKILL.md +59 -21
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-template-set/SKILL.md +20 -47
- package/dist/windsurf/.windsurf/skills/jahia-dev-create-view/SKILL.md +3 -3
- package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/SKILL.md +43 -486
- package/dist/windsurf/.windsurf/skills/jahia-dev-define-content-type/references/modeling-decisions.md +52 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/SKILL.md +79 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.d.mts +13 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-review-cnd/scripts/check-cnd.mjs +198 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/SKILL.md +70 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-site-review/scripts/review-pages.mjs +85 -0
- package/dist/windsurf/.windsurf/skills/jahia-dev-start-local/SKILL.md +18 -26
- package/dist/windsurf/.windsurf/skills/jahia-orchestrate/SKILL.md +148 -0
- package/dist/windsurf/.windsurf/skills/jahia-orchestrate/scripts/verify-pages.mjs +59 -0
- package/dist/windsurf/AGENTS.md +17 -8
- 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);
|
package/dist/gemini/AGENTS.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AGENTS.md
|
|
2
2
|
<!-- Generated by APM CLI from distributed .apm/ primitives -->
|
|
3
|
-
<!-- Build ID:
|
|
4
|
-
<!-- APM Version: 0.
|
|
3
|
+
<!-- Build ID: 4b60eae51ba0 -->
|
|
4
|
+
<!-- APM Version: 0.21.0 -->
|
|
5
5
|
|
|
6
6
|
## Global Instructions
|
|
7
7
|
|
|
@@ -14,15 +14,22 @@ You are helping develop a **Jahia JavaScript Module** — a React-based template
|
|
|
14
14
|
## Agent Principles
|
|
15
15
|
|
|
16
16
|
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.
|
|
17
|
+
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).
|
|
17
18
|
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).
|
|
19
|
+
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.
|
|
18
20
|
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.
|
|
19
21
|
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.
|
|
20
|
-
5. **Always verify before creating** — check that content types are deployed, site keys are correct, and area
|
|
22
|
+
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.
|
|
21
23
|
6. **All props are optional at runtime** — even mandatory CND fields. Always guard against `undefined` in views.
|
|
22
|
-
7. **
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
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.
|
|
25
|
+
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.
|
|
26
|
+
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.
|
|
27
|
+
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.
|
|
28
|
+
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.
|
|
29
|
+
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.
|
|
30
|
+
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.
|
|
31
|
+
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.
|
|
32
|
+
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.
|
|
26
33
|
|
|
27
34
|
## Skill Map
|
|
28
35
|
|
|
@@ -37,11 +44,13 @@ Start with `/jahia` if unsure where to begin.
|
|
|
37
44
|
| `/jahia-dev-start-local` | Start Jahia locally (Docker or bare metal) |
|
|
38
45
|
| `/jahia-dev-build-component` | Build a complete component (CND + view) — start here |
|
|
39
46
|
| `/jahia-dev-define-content-type` | Define a CND content type + types.ts |
|
|
47
|
+
| `/jahia-dev-review-cnd` | Validate a CND file for antipatterns — run after writing any CND |
|
|
40
48
|
| `/jahia-dev-create-view` | Implement a React view (.server.tsx + CSS Module) |
|
|
41
49
|
| `/jahia-dev-create-page-template` | Create a page template with Areas |
|
|
42
50
|
| `/jahia-dev-query-content` | Write JCR-SQL2 queries and useJCRQuery |
|
|
43
51
|
| `/jahia-dev-review` | Code review: 8 critical checks, 9 warnings, 11 suggestions |
|
|
44
|
-
| `/jahia-dev-
|
|
52
|
+
| `/jahia-dev-site-review` | Scored a11y + SEO report on live pages — use after every deploy |
|
|
53
|
+
| `/jahia-dev-accessibility` | Deep WCAG 2.1 AA audit with fixes — use for targeted a11y work |
|
|
45
54
|
| `/jahia-dev-screenshot` | Screenshot reference + local render for visual comparison |
|
|
46
55
|
| `/jahia-dev-debug` | Debug build/deploy/runtime errors end-to-end |
|
|
47
56
|
|
package/dist/gemini/GEMINI.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -969,6 +969,19 @@ if (interactive && overwriteCount > 0) {
|
|
|
969
969
|
} else if (overwriteCount > 0) R.warn(`Harness already exists, ${overwriteCount} file${overwriteCount >= 2 ? "s" : ""} will be overwritten.`);
|
|
970
970
|
for (const dir of dirsToCreate) mkdirSync(dir, { recursive: true });
|
|
971
971
|
for (const { src, dst } of filesToCopy) copyFileSync(src, dst);
|
|
972
|
+
if (target === "claude" && !process.env.CI) {
|
|
973
|
+
R.step("Installing TypeScript LSP plugin for Claude Code…");
|
|
974
|
+
const pluginInstall = spawnSync("claude", [
|
|
975
|
+
"plugin",
|
|
976
|
+
"install",
|
|
977
|
+
"typescript-lsp@claude-plugins-official"
|
|
978
|
+
], {
|
|
979
|
+
encoding: "utf-8",
|
|
980
|
+
timeout: 15e3
|
|
981
|
+
});
|
|
982
|
+
if (pluginInstall.error || pluginInstall.status !== 0) R.warn(`Could not install TypeScript LSP plugin automatically.\nRun manually: ${styleText("blueBright", "claude plugin install typescript-lsp@claude-plugins-official")}`);
|
|
983
|
+
else R.success("TypeScript LSP plugin installed.");
|
|
984
|
+
}
|
|
972
985
|
ye(`Harness created successfully!
|
|
973
986
|
|
|
974
987
|
To update the harness in the future, run ${styleText("blueBright", "npx @jahia/agentic@latest " + target)}`);
|
|
@@ -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
|
|
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
|
|
114
|
-
<img src={buildNodeUrl(props.image)} alt={props.
|
|
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
|
-
|
|
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
|
|
46
|
+
## Step 2 — REQUIRED: Invoke `/jahia-dev-define-content-type`
|
|
47
47
|
|
|
48
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
17
|
+
Page templates live in `src/templates/<ModuleName>Template/`. Name the file `default.server.tsx`.
|
|
18
18
|
|
|
19
19
|
```tsx
|
|
20
|
-
import
|
|
21
|
-
import {
|
|
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: "
|
|
28
|
-
name: "
|
|
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
|
-
```
|
|
123
|
-
|
|
124
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
|
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 `
|
|
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
|
-
// ✅
|
|
104
|
-
<img src={buildNodeUrl(props.image)} alt={props.
|
|
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
|
-
|
|
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
|
|