Instructions for AI coding agents operating in this repository.
Docusaurus 3 static documentation site (lucanerlich.com). Content covers AEM, Java, JavaScript, Strapi, and software design patterns. There is almost no application code -- the repo is primarily Markdown/MDX docs with minimal TypeScript/JS configuration and CSS.
- Framework: Docusaurus 3.9.x (
@docusaurus/preset-classic) - Package manager: pnpm 10.x (see
packageManagerinpackage.json) - Node version: ^22 (ignore the outdated
.nvmrcwhich says v16) - React: 19.x
- TypeScript: ~5.9.x
- Deployment: Docker multi-stage build, served via Coolify on port 3000
pnpm install # Install dependencies (always use pnpm, never npm/yarn)
pnpm start # Local dev server with hot reload
pnpm build # Production build (strict: throws on broken links/anchors)
pnpm serve # Serve production build locally
pnpm run coolify # Serve on port 3000 (production Docker target)
pnpm run clear # Clear Docusaurus cache (.docusaurus/)There is no test framework configured. No unit tests, integration tests, or
E2E tests exist. The only verification is pnpm build, which fails on:
- Broken internal links (
onBrokenLinks: 'throw') - Broken anchors (
onBrokenAnchors: 'throw') - Broken markdown links and images (via
markdown.hooks)
Always run pnpm build after making changes to verify nothing is broken.
Vale is configured for prose linting (.vale.ini):
vale docs/path/to/file.md # Lint a single file
vale docs/ # Lint all docsStyles: Microsoft, write-good, Vale built-ins. Applied to *.md and *.mdx.
- Indentation: 4 spaces (all files)
- Line endings: LF (Unix-style)
- Charset: UTF-8
- Final newline: Always insert trailing newline
- No ESLint or Prettier is configured; follow existing patterns
- Use
import typefor type-only imports (seedocusaurus.config.tsline 1-2) - Use single quotes for strings
- Use trailing commas in arrays and object literals
- Use
satisfiesfor type narrowing where appropriate - Use explicit type annotations for exported values
- Prefer
constoverlet; avoidvar - JSDoc comments with
@ts-checkfor.jsfiles (seesidebars.js) - CommonJS (
module.exports) for.jsconfig files consumed by Docusaurus - ES modules (
export default) for.tsconfig files - Section separators use comment blocks with dashes:
// ------------------------------------------------------------------ // Section name // ------------------------------------------------------------------
- Use CSS custom properties (
--custom-*) for theme tokens - Light/dark mode via
html[data-theme='dark']selector - Override Infima framework variables, do not fight the framework
- 4-space indentation, consistent with
.editorconfig
- Frontmatter fields:
title,description,slug,tags,keywords,sidebar_position,sidebar_label(not all required on every page) - File extensions:
.mdfor plain Markdown,.mdxfor files using JSX/components (Docusaurusmarkdown.format: 'detect'handles both automatically) - Headings: Start content with
# Title(H1), use H2/H3 for sections - Code blocks: Always include a language tag (
java,typescript, etc.) - Diagrams: Use Mermaid fenced code blocks (```mermaid)
- Links: Use relative paths to other docs (
./aem/architecture.mdx) - Em dashes: Use
--(double hyphen), not the Unicode em dash character - Categories: Define via
_category_.jsonwithlabeland optionalgeneratedIndexdescription - Prism languages available: groovy, java, rust, python, bash, yaml, csv (plus all Prism defaults)
- Sidebar ordering: Controlled by
sidebar-order.ts, notsidebar_positionfrontmatter. To reorder pages, edit the arrays in that file. - Trailing slashes: Enabled (
trailingSlash: true). All internal links should end with/or use relative file paths.
docusaurus.config.ts # Main site configuration (navbar, footer, plugins, redirects)
sidebar-order.ts # Sidebar ordering constants (edit here to reorder pages)
sidebars.js # Sidebar generator config (autogenerated from filesystem)
umami.js # Analytics client module (self-hosted Umami)
src/css/custom.css # Infima CSS overrides and theme tokens
src/pages/imprint.md # Legal imprint page
docs/ # All documentation content
intro.md # Homepage (slug: /)
aem/ # Adobe Experience Manager docs
strapi/ # Strapi CMS docs
javascript/ # JavaScript guides
java/ # Java guides
design-patterns/ # Design pattern catalog
other/ # Misc topics (shell, SQL, Docusaurus, etc.)
projects/ # Project showcases
static/ # Static assets (images, favicon, manifest.json)
.cursor/rules/ # 62 Cursor AI rules (performance + security)
- Broken link checking is strict --
pnpm buildwill fail on any broken link, anchor, markdown link, or image reference. Always verify after edits. - Blog is disabled (
blog: falsein preset config). - Client redirects are configured in
docusaurus.config.tsunder the@docusaurus/plugin-client-redirectsplugin. When moving/renaming docs, add a redirect from the old path to the new path. - Algolia search is configured -- no action needed from agents.
- Future flags:
experimental_faster: true(SWC) andv4: true.
The repo includes 62 Cursor rule files in two categories. These should be treated as project-level coding guidelines:
Organized into 8 sections: async, bundle, server, client, rerender, rendering, js, advanced. Key rules include:
- Eliminate async waterfalls (parallelize with
Promise.all) - Avoid barrel imports; use direct path imports
- Use dynamic imports /
React.lazyfor code splitting - Memoize expensive computations; use
useMemo/useCallbackappropriately - Hoist static JSX outside render; use conditional rendering
- Prefer
Set/Mapfor lookups; use early returns
Core principles enforced across all code:
- No raw user input in file access, command execution, or DB queries
- No exposed secrets in frontend code or public repos
- Validate all external input before use
- No sensitive data in logs
- Secure protocols only (HTTPS/TLS)
- No dynamic code execution (
eval,new Function, etc.) - No hardcoded credentials
- Fail securely on errors; default to secure configurations
- Apply defense in depth and least privilege
Language-specific security rules exist for: Java, Node.js, Python, Ruby, PHP, Rust, C, F#.
- Create a
.mdor.mdxfile under the appropriatedocs/subdirectory - Add frontmatter with at least
titleanddescription - If ordering matters, add the filename (without extension) to the appropriate
array in
sidebar-order.ts - Run
pnpm buildto verify no broken links
- Move/rename the file
- Add a redirect in
docusaurus.config.tsunderplugin-client-redirects - Update any internal links referencing the old path
- Update
sidebar-order.tsif the page was listed there - Run
pnpm buildto verify
- Create the directory under
docs/ - Add a
_category_.jsonwithlabeland optionalgeneratedIndex - Add the directory name to the parent's array in
sidebar-order.ts - Run
pnpm buildto verify
Node.js 22 and pnpm 10.x are required. The VM update script installs these automatically via NodeSource and corepack. No additional system dependencies are needed.
pnpm start --host 0.0.0.0 --port 3000Use --host 0.0.0.0 so the site is accessible from the Desktop browser pane.
The dev server supports hot reload; editing any .md, .mdx, .ts, .css,
or config file triggers an automatic rebuild.
There is no test suite. The verification steps are:
pnpm build-- the only "test". Fails on broken links, anchors, or images.pnpm start-- visually confirm the site renders correctly in a browser.
- No lockfile in repo:
pnpm-lock.yamlis gitignored.pnpm installgenerates it fresh each time. This means dependency versions may drift between environments;pnpm buildis the gate. .nvmrcsays v16: Ignore it. The correct Node version is^22perenginesinpackage.json.- No ESLint / Prettier: There are no JS/TS linters configured. The only prose linter is Vale (optional, not installed in the Cloud VM by default).
- SWC build warnings: The
vscode-languageserver-typescritical dependency warning duringpnpm buildis benign and can be ignored. - Algolia and Umami: Both are external services configured with public client-side keys. They are non-functional in local dev (Umami is skipped on localhost). No secrets are needed.