@nera-static/nera 1.5.1 → 1.6.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/README.md CHANGED
@@ -16,14 +16,15 @@ npm run dev # or: nera dev
16
16
 
17
17
  Already in the folder the site should live in? `nera new .` scaffolds into the
18
18
  current folder instead. The folder must be empty apart from dotfiles such as
19
- `.git` (an existing `.gitignore` is kept), and the package is named after the
20
- folder (`My Bakery` → `my-bakery`).
19
+ `.git` and an `AGENTS.md`/`CLAUDE.md` an AI assistant may have written first
20
+ (an existing `.gitignore`, `AGENTS.md` or `CLAUDE.md` is kept), and the
21
+ package is named after the folder (`My Bakery` → `my-bakery`).
21
22
 
22
23
  ## Commands
23
24
 
24
25
  | Command | What it does |
25
26
  |---|---|
26
- | `nera new <name>` | Scaffold a new thin Nera site (one dependency: `@nera-static/nera`). Add `--theme <name>` to start from a theme. `nera new .` scaffolds into the current, empty folder. |
27
+ | `nera new <name>` | Scaffold a new thin Nera site (one dependency: `@nera-static/nera`). Add `--theme <name>` to start from a theme. `nera new .` scaffolds into the current, empty folder (dotfiles, `AGENTS.md` and `CLAUDE.md` allowed). |
27
28
  | `nera build` | Render `pages/` → `public/`. With `--check`, then run `nera check` on the result — one command for CI. |
28
29
  | `nera dev` | Build, serve `public/`, and rebuild on change with live reload. Watches `pages/`, `config/`, `theme/` and a local theme (`theme: ./themes/<name>`). |
29
30
  | `nera serve` | Serve the already-built `public/` folder. |
@@ -41,6 +42,20 @@ dependency and its scripts call the CLI:
41
42
  }
42
43
  ```
43
44
 
45
+ ## Instructions for AI assistants
46
+
47
+ Every scaffolded site carries an `AGENTS.md`, the file Codex, Cursor, Copilot
48
+ and other assistants read first, and a `CLAUDE.md` holding the single line
49
+ `@AGENTS.md`, so Claude Code loads the same text. `AGENTS.md` covers what
50
+ Nera is, the folder map, the commands, the common traps, and the check loop:
51
+ `nera validate`, then `nera build --check`, after every change.
52
+
53
+ It ends with a **Notes for this site** section for your own instructions —
54
+ brand voice, pages not to touch, where the site is deployed. It starts below
55
+ the marker line `<!-- nera:site-notes … -->`; keep that line in place. The
56
+ part above it is Nera's and may be replaced by a later Nera version; your
57
+ notes below it are yours.
58
+
44
59
  ## Starting from a theme
45
60
 
46
61
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nera-static/nera",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "The Nera CLI — scaffold, build, preview and update a Nera static site with one command over the @nera-static/core engine",
5
5
  "type": "module",
6
6
  "bin": {
package/src/scaffold.js CHANGED
@@ -62,11 +62,18 @@ export function projectNameFromDir(dir) {
62
62
  : validateProjectName(name)
63
63
  }
64
64
 
65
+ // Files an AI assistant may have written before running `nera new .`. They
66
+ // do not make the folder count as non-empty, and the user's copy is kept.
67
+ // Exact names only, matched case-sensitively.
68
+ const AGENT_FILES = new Set(['AGENTS.md', 'CLAUDE.md'])
69
+
65
70
  // In-place scaffolding only goes ahead in an empty folder. Dotfiles such as
66
71
  // `.git` or an editor folder do not count: `git init` first is the usual way
67
- // to start a project.
72
+ // to start a project. Neither do AGENT_FILES.
68
73
  async function assertEmptyDir(dir) {
69
- const entries = (await fs.readdir(dir)).filter((n) => !n.startsWith('.'))
74
+ const entries = (await fs.readdir(dir)).filter(
75
+ (n) => !n.startsWith('.') && !AGENT_FILES.has(n)
76
+ )
70
77
  if (entries.length > 0) {
71
78
  throw new Error(
72
79
  `The current folder is not empty (${entries.slice(0, 3).join(', ')}` +
@@ -136,8 +143,9 @@ async function copyDir(src, dest, { skipStarters = false } = {}) {
136
143
  } else if (skipStarters && (await isStarterTemplate(from))) {
137
144
  continue
138
145
  } else if (fssync.existsSync(to)) {
139
- // Only in place, and then only a dotfile such as .gitignore can be
140
- // there already (assertEmptyDir): the user's copy wins.
146
+ // Only in place, and then only a dotfile such as .gitignore, or
147
+ // AGENTS.md / CLAUDE.md, can be there already (assertEmptyDir):
148
+ // the user's copy wins.
141
149
  console.log(` • Kept your existing ${path.basename(to)}`)
142
150
  } else {
143
151
  await fs.copyFile(from, to)
@@ -0,0 +1,118 @@
1
+ # AGENTS.md
2
+
3
+ Instructions for AI coding agents working on this site. People are welcome to
4
+ read them too.
5
+
6
+ ## What this is
7
+
8
+ This site is built with [Nera](https://nera.js.org), a static site generator:
9
+ Markdown pages plus Pug templates in, plain HTML out. Nera is not Eleventy,
10
+ Hugo, Astro or Jekyll, so do not apply their conventions here. The docs are
11
+ at https://nera.js.org.
12
+
13
+ ## Folder map
14
+
15
+ - `pages/` — the content: one Markdown file with YAML frontmatter per page
16
+ - `theme/views/` — the Pug templates (`layouts/`, `pages/`, and `vendor/`
17
+ for copied plugin templates)
18
+ - `theme/assets/` — CSS, JavaScript, images and fonts, copied into
19
+ `public/` on every build
20
+ - `config/` — YAML settings: `app.yaml` for the site, `<plugin>.yaml` for
21
+ each plugin
22
+ - `src/plugins/<name>/index.js` — local plugins for this site only (optional;
23
+ another folder can be set with `folders.plugins` in `config/app.yaml`)
24
+ - `public/` — the generated site. **Never edit it**: every build deletes it
25
+ and writes it again
26
+
27
+ ## Commands
28
+
29
+ - `npm run dev` — build, serve on http://localhost:3000 and rebuild on
30
+ every change
31
+ - `npm run build` — render `pages/` into `public/`
32
+ - `npx nera validate` — check pages, layouts, includes and YAML before a build
33
+ - `npx nera build --check` — build, then check the built `public/` for
34
+ accessibility, privacy and legal issues (`npx nera check` checks without
35
+ building)
36
+
37
+ ## After every change
38
+
39
+ 1. Run `npx nera validate` and fix every error it reports.
40
+ 2. Run `npx nera build --check` and fix what it reports.
41
+
42
+ `nera validate` names the file and line of a broken layout or include and
43
+ finds pages the build would skip silently. Run it first.
44
+
45
+ ## How Nera works (and where it trips agents up)
46
+
47
+ - **Pages are Markdown.** Write prose in Markdown, not HTML. Page structure
48
+ and markup shared between pages belong in `theme/views/`.
49
+ - **URLs end in `.html`.** `pages/a/b.md` becomes `public/a/b.html` and is
50
+ linked as `/a/b.html`; `pages/index.md` is `/index.html`. There are no
51
+ pretty URLs such as `/a/b/`.
52
+ - **A page needs `layout`.** The `layout` key in a page's frontmatter names a
53
+ file under `theme/views/`; the pages this site was created with use
54
+ `pages/default.pug`. A page without `layout` is not rendered and the build
55
+ says nothing; `nera validate` warns (`layout-missing`). Renaming or deleting
56
+ a layout breaks every page that uses it.
57
+ - **The page body.** The rendered Markdown reaches the template as `content`.
58
+ Without a theme, `theme/views/pages/default.pug` prints it with
59
+ `main !{ content }` inside `block content`; with a theme, the theme's layout
60
+ may already hold the `<main>`. A page has exactly one `<main>`: check the
61
+ layout and the page template before adding one.
62
+ - **`public/` is wiped on every build.** Put source files in `pages/`,
63
+ `theme/` or `config/`; anything written into `public/` by hand is lost.
64
+ - **Site files override theme files.** If `config/app.yaml` sets `theme:`,
65
+ the layouts come from that theme (a package or a folder), and a file in
66
+ `theme/views/` or `theme/assets/` replaces the theme's file at the same
67
+ path.
68
+ - **Translations.** Templates call `t('key')`, which reads
69
+ `translations.<lang>.key` from `config/app.yaml` (the page's `lang`, else
70
+ the site's).
71
+
72
+ ## Plugins: look for one before writing a feature
73
+
74
+ Features come from npm packages named `@nera-static/plugin-*`. Install one with
75
+ `npm install`, and Nera loads it on the next build; there is nothing to
76
+ register. Most read optional settings from `config/<name>.yaml` (the plugin's
77
+ README shows the keys). Plugin catalog:
78
+ https://github.com/seebaermichi/nera/blob/main/PLUGINS.md
79
+
80
+ Check the catalog before hand-writing navigation, a contact form, tags, search,
81
+ pagination or image handling. Two that sites often need:
82
+
83
+ - `@nera-static/plugin-contact-form` — a contact form that opens the visitor's
84
+ mail client (`mailto:`). No backend and no form service; configured in
85
+ `config/contact-form.yaml`.
86
+ - `@nera-static/plugin-navigation` — menus from `config/navigation.yaml`.
87
+
88
+ Plugin templates are not used automatically. Copy them into the site first,
89
+ then include them by hand in your own template:
90
+
91
+ - `npx nera-contact-form` copies the form to
92
+ `theme/views/vendor/plugin-contact-form/` (and its script to
93
+ `theme/assets/js/`); include it with
94
+ `include /vendor/plugin-contact-form/contact-form`
95
+ - `npx nera-navigation` copies the menus to
96
+ `theme/views/vendor/plugin-navigation/`
97
+
98
+ The copy is skipped when the target folder already exists, so later plugin
99
+ updates do not reach it; `--force` overwrites the copy.
100
+
101
+ ## Preview
102
+
103
+ `npm run dev` keeps running until it is stopped. If you start it in the
104
+ background, stop that process yourself when you are done, by its process ID.
105
+ Never kill processes by name (`pkill -f nera`), which stops other people's
106
+ servers too. If port 3000 is taken, the server picks another one and prints
107
+ the URL.
108
+
109
+ ## Getting online
110
+
111
+ `npm run build` writes the finished site into `public/`. That folder is what
112
+ gets deployed: upload its contents to any static web host.
113
+
114
+ <!-- nera:site-notes — everything below this line belongs to the site owner; `nera update` keeps it as it is -->
115
+ ## Notes for this site
116
+
117
+ Add what an agent should know about this particular site: its audience, tone,
118
+ languages, pages that must not change, the hosting.
@@ -0,0 +1 @@
1
+ @AGENTS.md